mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-12-23 21:33:08 +02:00
This commit is contained in:
parent
8b273e215f
commit
520299c2b4
169 changed files with 14582 additions and 14865 deletions
323
gulpfile.ts
323
gulpfile.ts
|
@ -189,231 +189,6 @@ gulp.task('build:client:scripts', done => {
|
||||||
.transform(ls)
|
.transform(ls)
|
||||||
.transform(aliasify, aliasifyConfig)
|
.transform(aliasify, aliasifyConfig)
|
||||||
|
|
||||||
.transform(transformify((source, file) => {
|
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
|
||||||
gutil.log('Build Tag: ' + file);
|
|
||||||
return source;
|
|
||||||
}))
|
|
||||||
|
|
||||||
// tagの{}の''を不要にする (その代わりスタイルの記法は使えなくなるけど)
|
|
||||||
.transform(transformify((source, file) => {
|
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
|
||||||
|
|
||||||
const tag = new Tag(source);
|
|
||||||
const html = tag.sections.filter(s => s.name == 'html')[0];
|
|
||||||
|
|
||||||
html.lines = html.lines.map(line => {
|
|
||||||
if (line.replace(/\t/g, '')[0] === '|') {
|
|
||||||
return line;
|
|
||||||
} else {
|
|
||||||
return line.replace(/([+=])\s?\{(.+?)\}/g, '$1"{$2}"');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const styles = tag.sections.filter(s => s.name == 'style');
|
|
||||||
|
|
||||||
if (styles.length == 0) {
|
|
||||||
return tag.compile();
|
|
||||||
}
|
|
||||||
|
|
||||||
styles.forEach(style => {
|
|
||||||
let head = style.lines.shift();
|
|
||||||
head = head.replace(/([+=])\s?\{(.+?)\}/g, '$1"{$2}"');
|
|
||||||
style.lines.unshift(head);
|
|
||||||
});
|
|
||||||
|
|
||||||
return tag.compile();
|
|
||||||
}))
|
|
||||||
|
|
||||||
// tagの@hogeをref='hoge'にする
|
|
||||||
.transform(transformify((source, file) => {
|
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
|
||||||
|
|
||||||
const tag = new Tag(source);
|
|
||||||
const html = tag.sections.filter(s => s.name == 'html')[0];
|
|
||||||
|
|
||||||
html.lines = html.lines.map(line => {
|
|
||||||
if (line.indexOf('@') === -1) {
|
|
||||||
return line;
|
|
||||||
} else if (line.replace(/\t/g, '')[0] === '|') {
|
|
||||||
return line;
|
|
||||||
} else {
|
|
||||||
while (line.match(/[^\s']@[a-z-]+/) !== null) {
|
|
||||||
const match = line.match(/@[a-z-]+/);
|
|
||||||
let name = match[0];
|
|
||||||
if (line[line.indexOf(name) + name.length] === '(') {
|
|
||||||
line = line.replace(name + '(', '(ref=\'' + camelCase(name.substr(1)) + '\',');
|
|
||||||
} else {
|
|
||||||
line = line.replace(name, '(ref=\'' + camelCase(name.substr(1)) + '\')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return tag.compile();
|
|
||||||
|
|
||||||
function camelCase(str): string {
|
|
||||||
return str.replace(/-([^\s])/g, (match, group1) => {
|
|
||||||
return group1.toUpperCase();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
// tagのchain-caseをcamelCaseにする
|
|
||||||
.transform(transformify((source, file) => {
|
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
|
||||||
|
|
||||||
const tag = new Tag(source);
|
|
||||||
const html = tag.sections.filter(s => s.name == 'html')[0];
|
|
||||||
|
|
||||||
html.lines = html.lines.map(line => {
|
|
||||||
(line.match(/\{.+?\}/g) || []).forEach(x => {
|
|
||||||
line = line.replace(x, camelCase(x));
|
|
||||||
});
|
|
||||||
return line;
|
|
||||||
});
|
|
||||||
|
|
||||||
return tag.compile();
|
|
||||||
|
|
||||||
function camelCase(str): string {
|
|
||||||
str = str.replace(/([a-z\-]+):/g, (match, group1) => {
|
|
||||||
return group1.replace(/\-/g, '###') + ':';
|
|
||||||
});
|
|
||||||
str = str.replace(/'(.+?)'/g, (match, group1) => {
|
|
||||||
return "'" + group1.replace(/\-/g, '###') + "'";
|
|
||||||
});
|
|
||||||
str = str.replace(/-([^\s0-9])/g, (match, group1) => {
|
|
||||||
return group1.toUpperCase();
|
|
||||||
});
|
|
||||||
str = str.replace(/###/g, '-');
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
// tagのstyleの属性
|
|
||||||
.transform(transformify((source, file) => {
|
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
|
||||||
|
|
||||||
const tag = new Tag(source);
|
|
||||||
|
|
||||||
const styles = tag.sections.filter(s => s.name == 'style');
|
|
||||||
|
|
||||||
if (styles.length == 0) {
|
|
||||||
return tag.compile();
|
|
||||||
}
|
|
||||||
|
|
||||||
styles.forEach(style => {
|
|
||||||
let head = style.lines.shift();
|
|
||||||
if (style.attr) {
|
|
||||||
style.attr = style.attr + ', type=\'stylus\', scoped';
|
|
||||||
} else {
|
|
||||||
style.attr = 'type=\'stylus\', scoped';
|
|
||||||
}
|
|
||||||
style.lines.unshift(head);
|
|
||||||
});
|
|
||||||
|
|
||||||
return tag.compile();
|
|
||||||
}))
|
|
||||||
|
|
||||||
// tagのstyleの定数
|
|
||||||
.transform(transformify((source, file) => {
|
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
|
||||||
|
|
||||||
const tag = new Tag(source);
|
|
||||||
|
|
||||||
const styles = tag.sections.filter(s => s.name == 'style');
|
|
||||||
|
|
||||||
if (styles.length == 0) {
|
|
||||||
return tag.compile();
|
|
||||||
}
|
|
||||||
|
|
||||||
styles.forEach(style => {
|
|
||||||
const head = style.lines.shift();
|
|
||||||
style.lines.unshift('$theme-color = ' + config.themeColor);
|
|
||||||
style.lines.unshift('$theme-color-foreground = #fff');
|
|
||||||
style.lines.unshift(head);
|
|
||||||
});
|
|
||||||
|
|
||||||
return tag.compile();
|
|
||||||
}))
|
|
||||||
|
|
||||||
// tagのstyleを暗黙的に:scopeにする
|
|
||||||
.transform(transformify((source, file) => {
|
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
|
||||||
|
|
||||||
const tag = new Tag(source);
|
|
||||||
|
|
||||||
const styles = tag.sections.filter(s => s.name == 'style');
|
|
||||||
|
|
||||||
if (styles.length == 0) {
|
|
||||||
return tag.compile();
|
|
||||||
}
|
|
||||||
|
|
||||||
styles.forEach((style, i) => {
|
|
||||||
if (i != 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const head = style.lines.shift();
|
|
||||||
style.lines = style.lines.map(line => {
|
|
||||||
return '\t' + line;
|
|
||||||
});
|
|
||||||
style.lines.unshift(':scope');
|
|
||||||
style.lines.unshift(head);
|
|
||||||
});
|
|
||||||
|
|
||||||
return tag.compile();
|
|
||||||
}))
|
|
||||||
|
|
||||||
// tagのtheme styleのパース
|
|
||||||
.transform(transformify((source, file) => {
|
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
|
||||||
|
|
||||||
const tag = new Tag(source);
|
|
||||||
|
|
||||||
const styles = tag.sections.filter(s => s.name == 'style');
|
|
||||||
|
|
||||||
if (styles.length == 0) {
|
|
||||||
return tag.compile();
|
|
||||||
}
|
|
||||||
|
|
||||||
styles.forEach((style, i) => {
|
|
||||||
if (i == 0) {
|
|
||||||
return;
|
|
||||||
} else if (style.attr.substr(0, 6) != 'theme=') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const head = style.lines.shift();
|
|
||||||
style.lines = style.lines.map(line => {
|
|
||||||
return '\t' + line;
|
|
||||||
});
|
|
||||||
style.lines.unshift(':scope');
|
|
||||||
style.lines = style.lines.map(line => {
|
|
||||||
return '\t' + line;
|
|
||||||
});
|
|
||||||
style.lines.unshift('html[data-' + style.attr.match(/theme='(.+?)'/)[0] + ']');
|
|
||||||
style.lines.unshift(head);
|
|
||||||
});
|
|
||||||
|
|
||||||
return tag.compile();
|
|
||||||
}))
|
|
||||||
|
|
||||||
// tagのstyleおよびscriptのインデントを不要にする
|
|
||||||
.transform(transformify((source, file) => {
|
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
|
||||||
const tag = new Tag(source);
|
|
||||||
|
|
||||||
tag.sections = tag.sections.map(section => {
|
|
||||||
if (section.name != 'html') {
|
|
||||||
section.indent++;
|
|
||||||
}
|
|
||||||
return section;
|
|
||||||
});
|
|
||||||
|
|
||||||
return tag.compile();
|
|
||||||
}))
|
|
||||||
|
|
||||||
// スペースでインデントされてないとエラーが出る
|
// スペースでインデントされてないとエラーが出る
|
||||||
.transform(transformify((source, file) => {
|
.transform(transformify((source, file) => {
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
if (file.substr(-4) !== '.tag') return source;
|
||||||
|
@ -423,6 +198,8 @@ gulp.task('build:client:scripts', done => {
|
||||||
.transform(transformify((source, file) => {
|
.transform(transformify((source, file) => {
|
||||||
return source
|
return source
|
||||||
.replace(/VERSION/g, `'${commit ? commit.hash : 'null'}'`)
|
.replace(/VERSION/g, `'${commit ? commit.hash : 'null'}'`)
|
||||||
|
.replace(/\$theme\-color\-foreground/g, '#fff')
|
||||||
|
.replace(/\$theme\-color/g, config.themeColor)
|
||||||
.replace(/CONFIG\.theme-color/g, `'${config.themeColor}'`)
|
.replace(/CONFIG\.theme-color/g, `'${config.themeColor}'`)
|
||||||
.replace(/CONFIG\.themeColor/g, `'${config.themeColor}'`)
|
.replace(/CONFIG\.themeColor/g, `'${config.themeColor}'`)
|
||||||
.replace(/CONFIG\.api\.url/g, `'${config.scheme}://api.${config.host}'`)
|
.replace(/CONFIG\.api\.url/g, `'${config.scheme}://api.${config.host}'`)
|
||||||
|
@ -435,7 +212,6 @@ gulp.task('build:client:scripts', done => {
|
||||||
}))
|
}))
|
||||||
|
|
||||||
.transform(riotify, {
|
.transform(riotify, {
|
||||||
template: 'pug',
|
|
||||||
type: 'livescript',
|
type: 'livescript',
|
||||||
expr: false,
|
expr: false,
|
||||||
compact: true,
|
compact: true,
|
||||||
|
@ -446,17 +222,6 @@ gulp.task('build:client:scripts', done => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Riotが謎の空白を挿入する
|
|
||||||
.transform(transformify((source, file) => {
|
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
|
||||||
return source.replace(/\s<mk\-ellipsis>/g, '<mk-ellipsis>');
|
|
||||||
}))
|
|
||||||
/*
|
|
||||||
// LiveScruptがHTMLクラスのショートカットを変な風に生成するのでそれを修正
|
|
||||||
.transform(transformify((source, file) => {
|
|
||||||
if (file.substr(-4) !== '.tag') return source;
|
|
||||||
return source.replace(/class="\{\(\{(.+?)\}\)\}"/g, 'class="{$1}"');
|
|
||||||
}))*/
|
|
||||||
.bundle()
|
.bundle()
|
||||||
.pipe(source(entry.replace('./src/web/app/', './').replace('.ls', '.js')));
|
.pipe(source(entry.replace('./src/web/app/', './').replace('.ls', '.js')));
|
||||||
|
|
||||||
|
@ -531,87 +296,3 @@ gulp.task('build:client:pug', [
|
||||||
}))
|
}))
|
||||||
.pipe(gulp.dest('./built/web/app/'));
|
.pipe(gulp.dest('./built/web/app/'));
|
||||||
});
|
});
|
||||||
|
|
||||||
class Tag {
|
|
||||||
sections: {
|
|
||||||
name: string;
|
|
||||||
attr?: string;
|
|
||||||
indent: number;
|
|
||||||
lines: string[];
|
|
||||||
}[];
|
|
||||||
|
|
||||||
constructor(source) {
|
|
||||||
this.sections = [];
|
|
||||||
|
|
||||||
source = source
|
|
||||||
.replace(/\r\n/g, '\n')
|
|
||||||
.replace(/\n(\t+?)\n/g, '\n')
|
|
||||||
.replace(/\n+/g, '\n');
|
|
||||||
|
|
||||||
const html = {
|
|
||||||
name: 'html',
|
|
||||||
indent: 0,
|
|
||||||
lines: []
|
|
||||||
};
|
|
||||||
|
|
||||||
let flag = false;
|
|
||||||
source.split('\n').forEach((line, i) => {
|
|
||||||
const indent = line.lastIndexOf('\t') + 1;
|
|
||||||
if (i != 0 && indent == 0) {
|
|
||||||
flag = true;
|
|
||||||
}
|
|
||||||
if (!flag) {
|
|
||||||
source = source.replace(/^.*?\n/, '');
|
|
||||||
html.lines.push(i == 0 ? line : line.substr(1));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.sections.push(html);
|
|
||||||
|
|
||||||
while (source != '') {
|
|
||||||
const line = source.substr(0, source.indexOf('\n'));
|
|
||||||
const root = line.match(/^\t*([a-z]+)(\.|\()?/)[1];
|
|
||||||
const beginIndent = line.lastIndexOf('\t') + 1;
|
|
||||||
flag = false;
|
|
||||||
const section = {
|
|
||||||
name: root,
|
|
||||||
attr: (line.match(/\((.+?)\)/) || [null, null])[1],
|
|
||||||
indent: beginIndent,
|
|
||||||
lines: []
|
|
||||||
};
|
|
||||||
source.split('\n').forEach((line, i) => {
|
|
||||||
const currentIndent = line.lastIndexOf('\t') + 1;
|
|
||||||
if (i != 0 && (currentIndent == beginIndent || currentIndent == 0)) {
|
|
||||||
flag = true;
|
|
||||||
}
|
|
||||||
if (!flag) {
|
|
||||||
if (i == 0 && line[line.length - 1] == '.') {
|
|
||||||
line = line.substr(0, line.length - 1);
|
|
||||||
}
|
|
||||||
if (i == 0 && line.indexOf('(') != -1) {
|
|
||||||
line = line.substr(0, line.indexOf('('));
|
|
||||||
}
|
|
||||||
source = source.replace(/^.*?\n/, '');
|
|
||||||
section.lines.push(i == 0 ? line.substr(beginIndent) : line.substr(beginIndent + 1));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.sections.push(section);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compile(): string {
|
|
||||||
let dist = '';
|
|
||||||
this.sections.forEach((section, j) => {
|
|
||||||
dist += section.lines.map((line, i) => {
|
|
||||||
if (i == 0) {
|
|
||||||
const attr = section.attr != null ? '(' + section.attr + ')' : '';
|
|
||||||
const tail = j != 0 ? '.' : '';
|
|
||||||
return '\t'.repeat(section.indent) + line + attr + tail;
|
|
||||||
} else {
|
|
||||||
return '\t'.repeat(section.indent + 1) + line;
|
|
||||||
}
|
|
||||||
}).join('\n') + '\n';
|
|
||||||
});
|
|
||||||
return dist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,126 +1,126 @@
|
||||||
mk-form
|
<mk-form>
|
||||||
header
|
<header>
|
||||||
h1
|
<h1><i>{ app.name }</i>があなたの<b>アカウント</b>に<b>アクセス</b>することを<b>許可</b>しますか?</h1><img src="{ app.icon_url + '?thumbnail&size=64' }"/>
|
||||||
i { app.name }
|
</header>
|
||||||
| があなたの
|
<div class="app">
|
||||||
b アカウント
|
<section>
|
||||||
| に
|
<h2>{ app.name }</h2>
|
||||||
b アクセス
|
<p class="nid">{ app.name_id }</p>
|
||||||
| することを
|
<p class="description">{ app.description }</p>
|
||||||
b 許可
|
</section>
|
||||||
| しますか?
|
<section>
|
||||||
img(src={ app.icon_url + '?thumbnail&size=64' })
|
<h2>このアプリは次の権限を要求しています:</h2>
|
||||||
div.app
|
<ul>
|
||||||
section
|
<virtual each="{ p in app.permission }">
|
||||||
h2 { app.name }
|
<li if="{ p == 'account-read' }">アカウントの情報を見る。</li>
|
||||||
p.nid { app.name_id }
|
<li if="{ p == 'account-write' }">アカウントの情報を操作する。</li>
|
||||||
p.description { app.description }
|
<li if="{ p == 'post-write' }">投稿する。</li>
|
||||||
section
|
<li if="{ p == 'like-write' }">いいねしたりいいね解除する。</li>
|
||||||
h2 このアプリは次の権限を要求しています:
|
<li if="{ p == 'following-write' }">フォローしたりフォロー解除する。</li>
|
||||||
ul
|
<li if="{ p == 'drive-read' }">ドライブを見る。</li>
|
||||||
virtual(each={ p in app.permission })
|
<li if="{ p == 'drive-write' }">ドライブを操作する。</li>
|
||||||
li(if={ p == 'account-read' }) アカウントの情報を見る。
|
<li if="{ p == 'notification-read' }">通知を見る。</li>
|
||||||
li(if={ p == 'account-write' }) アカウントの情報を操作する。
|
<li if="{ p == 'notification-write' }">通知を操作する。</li>
|
||||||
li(if={ p == 'post-write' }) 投稿する。
|
</virtual>
|
||||||
li(if={ p == 'like-write' }) いいねしたりいいね解除する。
|
</ul>
|
||||||
li(if={ p == 'following-write' }) フォローしたりフォロー解除する。
|
</section>
|
||||||
li(if={ p == 'drive-read' }) ドライブを見る。
|
</div>
|
||||||
li(if={ p == 'drive-write' }) ドライブを操作する。
|
<div class="action">
|
||||||
li(if={ p == 'notification-read' }) 通知を見る。
|
<button onclick="{ cancel }">キャンセル</button>
|
||||||
li(if={ p == 'notification-write' }) 通知を操作する。
|
<button onclick="{ accept }">アクセスを許可</button>
|
||||||
|
</div>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
div.action
|
> header
|
||||||
button(onclick={ cancel }) キャンセル
|
> h1
|
||||||
button(onclick={ accept }) アクセスを許可
|
margin 0
|
||||||
|
padding 32px 32px 20px 32px
|
||||||
|
font-size 24px
|
||||||
|
font-weight normal
|
||||||
|
color #777
|
||||||
|
|
||||||
style.
|
i
|
||||||
display block
|
color #77aeca
|
||||||
|
|
||||||
> header
|
&:before
|
||||||
> h1
|
content '「'
|
||||||
margin 0
|
|
||||||
padding 32px 32px 20px 32px
|
|
||||||
font-size 24px
|
|
||||||
font-weight normal
|
|
||||||
color #777
|
|
||||||
|
|
||||||
i
|
&:after
|
||||||
color #77aeca
|
content '」'
|
||||||
|
|
||||||
&:before
|
b
|
||||||
content '「'
|
color #666
|
||||||
|
|
||||||
|
> img
|
||||||
|
display block
|
||||||
|
z-index 1
|
||||||
|
width 84px
|
||||||
|
height 84px
|
||||||
|
margin 0 auto -38px auto
|
||||||
|
border solid 5px #fff
|
||||||
|
border-radius 100%
|
||||||
|
box-shadow 0 2px 2px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
|
> .app
|
||||||
|
padding 44px 16px 0 16px
|
||||||
|
color #555
|
||||||
|
background #eee
|
||||||
|
box-shadow 0 2px 2px rgba(0, 0, 0, 0.1) inset
|
||||||
|
|
||||||
&:after
|
&:after
|
||||||
content '」'
|
content ''
|
||||||
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
b
|
> section
|
||||||
color #666
|
float left
|
||||||
|
width 50%
|
||||||
|
padding 8px
|
||||||
|
text-align left
|
||||||
|
|
||||||
> img
|
> h2
|
||||||
display block
|
margin 0
|
||||||
z-index 1
|
font-size 16px
|
||||||
width 84px
|
color #777
|
||||||
height 84px
|
|
||||||
margin 0 auto -38px auto
|
|
||||||
border solid 5px #fff
|
|
||||||
border-radius 100%
|
|
||||||
box-shadow 0 2px 2px rgba(0, 0, 0, 0.1)
|
|
||||||
|
|
||||||
> .app
|
> .action
|
||||||
padding 44px 16px 0 16px
|
padding 16px
|
||||||
color #555
|
|
||||||
background #eee
|
|
||||||
box-shadow 0 2px 2px rgba(0, 0, 0, 0.1) inset
|
|
||||||
|
|
||||||
&:after
|
> button
|
||||||
content ''
|
margin 0 8px
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
> section
|
@media (max-width 600px)
|
||||||
float left
|
> header
|
||||||
width 50%
|
> img
|
||||||
padding 8px
|
box-shadow none
|
||||||
text-align left
|
|
||||||
|
|
||||||
> h2
|
> .app
|
||||||
margin 0
|
box-shadow none
|
||||||
font-size 16px
|
|
||||||
color #777
|
|
||||||
|
|
||||||
> .action
|
@media (max-width 500px)
|
||||||
padding 16px
|
> header
|
||||||
|
> h1
|
||||||
|
font-size 16px
|
||||||
|
|
||||||
> button
|
</style>
|
||||||
margin 0 8px
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
|
||||||
@media (max-width 600px)
|
@session = @opts.session
|
||||||
> header
|
@app = @session.app
|
||||||
> img
|
|
||||||
box-shadow none
|
|
||||||
|
|
||||||
> .app
|
@cancel = ~>
|
||||||
box-shadow none
|
@api \auth/deny do
|
||||||
|
token: @session.token
|
||||||
|
.then ~>
|
||||||
|
@trigger \denied
|
||||||
|
|
||||||
@media (max-width 500px)
|
@accept = ~>
|
||||||
> header
|
@api \auth/accept do
|
||||||
> h1
|
token: @session.token
|
||||||
font-size 16px
|
.then ~>
|
||||||
|
@trigger \accepted
|
||||||
script.
|
</script>
|
||||||
@mixin \api
|
</mk-form>
|
||||||
|
|
||||||
@session = @opts.session
|
|
||||||
@app = @session.app
|
|
||||||
|
|
||||||
@cancel = ~>
|
|
||||||
@api \auth/deny do
|
|
||||||
token: @session.token
|
|
||||||
.then ~>
|
|
||||||
@trigger \denied
|
|
||||||
|
|
||||||
@accept = ~>
|
|
||||||
@api \auth/accept do
|
|
||||||
token: @session.token
|
|
||||||
.then ~>
|
|
||||||
@trigger \accepted
|
|
||||||
|
|
|
@ -1,129 +1,136 @@
|
||||||
mk-index
|
<mk-index>
|
||||||
main(if={ SIGNIN })
|
<main if="{ SIGNIN }">
|
||||||
p.fetching(if={ fetching })
|
<p class="fetching" if="{ fetching }">読み込み中
|
||||||
| 読み込み中
|
<mk-ellipsis></mk-ellipsis>
|
||||||
mk-ellipsis
|
</p>
|
||||||
mk-form@form(if={ state == null && !fetching }, session={ session })
|
<mk-form ref="form" if="{ state == null && !fetching }" session="{ session }"></mk-form>
|
||||||
div.denied(if={ state == 'denied' })
|
<div class="denied" if="{ state == 'denied' }">
|
||||||
h1 アプリケーションの連携をキャンセルしました。
|
<h1>アプリケーションの連携をキャンセルしました。</h1>
|
||||||
p このアプリがあなたのアカウントにアクセスすることはありません。
|
<p>このアプリがあなたのアカウントにアクセスすることはありません。</p>
|
||||||
div.accepted(if={ state == 'accepted' })
|
</div>
|
||||||
h1 { session.app.is_authorized ? 'このアプリは既に連携済みです' : 'アプリケーションの連携を許可しました'}
|
<div class="accepted" if="{ state == 'accepted' }">
|
||||||
p(if={ session.app.callback_url })
|
<h1>{ session.app.is_authorized ? 'このアプリは既に連携済みです' : 'アプリケーションの連携を許可しました'}</h1>
|
||||||
| アプリケーションに戻っています
|
<p if="{ session.app.callback_url }">アプリケーションに戻っています
|
||||||
mk-ellipsis
|
<mk-ellipsis></mk-ellipsis>
|
||||||
p(if={ !session.app.callback_url }) アプリケーションに戻って、やっていってください。
|
</p>
|
||||||
div.error(if={ state == 'fetch-session-error' })
|
<p if="{ !session.app.callback_url }">アプリケーションに戻って、やっていってください。</p>
|
||||||
p セッションが存在しません。
|
</div>
|
||||||
main.signin(if={ !SIGNIN })
|
<div class="error" if="{ state == 'fetch-session-error' }">
|
||||||
h1 サインインしてください
|
<p>セッションが存在しません。</p>
|
||||||
mk-signin
|
</div>
|
||||||
footer
|
</main>
|
||||||
img(src='/_/resources/auth/logo.svg', alt='Misskey')
|
<main class="signin" if="{ !SIGNIN }">
|
||||||
|
<h1>サインインしてください</h1>
|
||||||
style.
|
<mk-signin></mk-signin>
|
||||||
display block
|
</main>
|
||||||
|
<footer><img src="/_/resources/auth/logo.svg" alt="Misskey"/></footer>
|
||||||
> main
|
<style type="stylus">
|
||||||
width 100%
|
:scope
|
||||||
max-width 500px
|
|
||||||
margin 0 auto
|
|
||||||
text-align center
|
|
||||||
background #fff
|
|
||||||
box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
|
|
||||||
|
|
||||||
> .fetching
|
|
||||||
margin 0
|
|
||||||
padding 32px
|
|
||||||
color #555
|
|
||||||
|
|
||||||
> div
|
|
||||||
padding 64px
|
|
||||||
|
|
||||||
> h1
|
|
||||||
margin 0 0 8px 0
|
|
||||||
padding 0
|
|
||||||
font-size 20px
|
|
||||||
font-weight normal
|
|
||||||
|
|
||||||
> p
|
|
||||||
margin 0
|
|
||||||
color #555
|
|
||||||
|
|
||||||
&.denied > h1
|
|
||||||
color #e65050
|
|
||||||
|
|
||||||
&.accepted > h1
|
|
||||||
color #50bbe6
|
|
||||||
|
|
||||||
&.signin
|
|
||||||
padding 32px 32px 16px 32px
|
|
||||||
|
|
||||||
> h1
|
|
||||||
margin 0 0 22px 0
|
|
||||||
padding 0
|
|
||||||
font-size 20px
|
|
||||||
font-weight normal
|
|
||||||
color #555
|
|
||||||
|
|
||||||
@media (max-width 600px)
|
|
||||||
max-width none
|
|
||||||
box-shadow none
|
|
||||||
|
|
||||||
@media (max-width 500px)
|
|
||||||
> div
|
|
||||||
> h1
|
|
||||||
font-size 16px
|
|
||||||
|
|
||||||
> footer
|
|
||||||
> img
|
|
||||||
display block
|
display block
|
||||||
width 64px
|
|
||||||
height 64px
|
|
||||||
margin 0 auto
|
|
||||||
|
|
||||||
script.
|
> main
|
||||||
@mixin \i
|
width 100%
|
||||||
@mixin \api
|
max-width 500px
|
||||||
|
margin 0 auto
|
||||||
|
text-align center
|
||||||
|
background #fff
|
||||||
|
box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
@state = null
|
> .fetching
|
||||||
@fetching = true
|
margin 0
|
||||||
|
padding 32px
|
||||||
|
color #555
|
||||||
|
|
||||||
@token = window.location.href.split \/ .pop!
|
> div
|
||||||
|
padding 64px
|
||||||
|
|
||||||
@on \mount ~>
|
> h1
|
||||||
if not @SIGNIN then return
|
margin 0 0 8px 0
|
||||||
|
padding 0
|
||||||
|
font-size 20px
|
||||||
|
font-weight normal
|
||||||
|
|
||||||
# Fetch session
|
> p
|
||||||
@api \auth/session/show do
|
margin 0
|
||||||
token: @token
|
color #555
|
||||||
.then (session) ~>
|
|
||||||
@session = session
|
|
||||||
@fetching = false
|
|
||||||
|
|
||||||
# 既に連携していた場合
|
&.denied > h1
|
||||||
if @session.app.is_authorized
|
color #e65050
|
||||||
@api \auth/accept do
|
|
||||||
token: @session.token
|
|
||||||
.then ~>
|
|
||||||
@accepted!
|
|
||||||
else
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@refs.form.on \denied ~>
|
&.accepted > h1
|
||||||
@state = \denied
|
color #50bbe6
|
||||||
|
|
||||||
|
&.signin
|
||||||
|
padding 32px 32px 16px 32px
|
||||||
|
|
||||||
|
> h1
|
||||||
|
margin 0 0 22px 0
|
||||||
|
padding 0
|
||||||
|
font-size 20px
|
||||||
|
font-weight normal
|
||||||
|
color #555
|
||||||
|
|
||||||
|
@media (max-width 600px)
|
||||||
|
max-width none
|
||||||
|
box-shadow none
|
||||||
|
|
||||||
|
@media (max-width 500px)
|
||||||
|
> div
|
||||||
|
> h1
|
||||||
|
font-size 16px
|
||||||
|
|
||||||
|
> footer
|
||||||
|
> img
|
||||||
|
display block
|
||||||
|
width 64px
|
||||||
|
height 64px
|
||||||
|
margin 0 auto
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mixin \api
|
||||||
|
|
||||||
|
@state = null
|
||||||
|
@fetching = true
|
||||||
|
|
||||||
|
@token = window.location.href.split \/ .pop!
|
||||||
|
|
||||||
|
@on \mount ~>
|
||||||
|
if not @SIGNIN then return
|
||||||
|
|
||||||
|
# Fetch session
|
||||||
|
@api \auth/session/show do
|
||||||
|
token: @token
|
||||||
|
.then (session) ~>
|
||||||
|
@session = session
|
||||||
|
@fetching = false
|
||||||
|
|
||||||
|
# 既に連携していた場合
|
||||||
|
if @session.app.is_authorized
|
||||||
|
@api \auth/accept do
|
||||||
|
token: @session.token
|
||||||
|
.then ~>
|
||||||
|
@accepted!
|
||||||
|
else
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
@refs.form.on \accepted @accepted
|
@refs.form.on \denied ~>
|
||||||
|
@state = \denied
|
||||||
|
@update!
|
||||||
|
|
||||||
.catch (error) ~>
|
@refs.form.on \accepted @accepted
|
||||||
@fetching = false
|
|
||||||
@state = \fetch-session-error
|
.catch (error) ~>
|
||||||
|
@fetching = false
|
||||||
|
@state = \fetch-session-error
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@accepted = ~>
|
||||||
|
@state = \accepted
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
@accepted = ~>
|
if @session.app.callback_url
|
||||||
@state = \accepted
|
location.href = @session.app.callback_url + '?token=' + @session.token
|
||||||
@update!
|
</script>
|
||||||
|
</mk-index>
|
||||||
if @session.app.callback_url
|
|
||||||
location.href = @session.app.callback_url + '?token=' + @session.token
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
mk-copyright
|
<mk-copyright><span>(c) syuilo 2014-2017</span>
|
||||||
span (c) syuilo 2014-2017
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</mk-copyright>
|
||||||
|
|
|
@ -1,63 +1,64 @@
|
||||||
mk-core-error
|
<mk-core-error>
|
||||||
//i: i.fa.fa-times-circle
|
<!--i: i.fa.fa-times-circle--><img src="/_/resources/error.jpg" alt=""/>
|
||||||
img(src='/_/resources/error.jpg', alt='')
|
<h1>
|
||||||
h1: mk-ripple-string サーバーに接続できません
|
<mk-ripple-string>サーバーに接続できません</mk-ripple-string>
|
||||||
p.text
|
</h1>
|
||||||
| インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから
|
<p class="text">インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから<a onclick="{ retry }">再度お試し</a>ください。</p>
|
||||||
a(onclick={ retry }) 再度お試し
|
<p class="thanks">いつもMisskeyをご利用いただきありがとうございます。</p>
|
||||||
| ください。
|
<style type="stylus">
|
||||||
p.thanks いつもMisskeyをご利用いただきありがとうございます。
|
:scope
|
||||||
|
position fixed
|
||||||
|
z-index 16385
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
text-align center
|
||||||
|
background #f8f8f8
|
||||||
|
|
||||||
style.
|
> i
|
||||||
position fixed
|
display block
|
||||||
z-index 16385
|
margin-top 64px
|
||||||
top 0
|
font-size 5em
|
||||||
left 0
|
color #6998a0
|
||||||
width 100%
|
|
||||||
height 100%
|
|
||||||
text-align center
|
|
||||||
background #f8f8f8
|
|
||||||
|
|
||||||
> i
|
> img
|
||||||
display block
|
display block
|
||||||
margin-top 64px
|
height 200px
|
||||||
font-size 5em
|
margin 64px auto 0 auto
|
||||||
color #6998a0
|
pointer-events none
|
||||||
|
-ms-user-select none
|
||||||
|
-moz-user-select none
|
||||||
|
-webkit-user-select none
|
||||||
|
user-select none
|
||||||
|
|
||||||
> img
|
> h1
|
||||||
display block
|
display block
|
||||||
height 200px
|
margin 32px auto 16px auto
|
||||||
margin 64px auto 0 auto
|
font-size 1.5em
|
||||||
pointer-events none
|
color #555
|
||||||
-ms-user-select none
|
|
||||||
-moz-user-select none
|
|
||||||
-webkit-user-select none
|
|
||||||
user-select none
|
|
||||||
|
|
||||||
> h1
|
> .text
|
||||||
display block
|
display block
|
||||||
margin 32px auto 16px auto
|
margin 0 auto
|
||||||
font-size 1.5em
|
max-width 600px
|
||||||
color #555
|
font-size 1em
|
||||||
|
color #666
|
||||||
|
|
||||||
> .text
|
> .thanks
|
||||||
display block
|
display block
|
||||||
margin 0 auto
|
margin 32px auto 0 auto
|
||||||
max-width 600px
|
padding 32px 0 32px 0
|
||||||
font-size 1em
|
max-width 600px
|
||||||
color #666
|
font-size 0.9em
|
||||||
|
font-style oblique
|
||||||
|
color #aaa
|
||||||
|
border-top solid 1px #eee
|
||||||
|
|
||||||
> .thanks
|
</style>
|
||||||
display block
|
<script>
|
||||||
margin 32px auto 0 auto
|
@retry = ~>
|
||||||
padding 32px 0 32px 0
|
@unmount!
|
||||||
max-width 600px
|
@opts.retry!
|
||||||
font-size 0.9em
|
</script>
|
||||||
font-style oblique
|
</mk-core-error>
|
||||||
color #aaa
|
|
||||||
border-top solid 1px #eee
|
|
||||||
|
|
||||||
script.
|
|
||||||
@retry = ~>
|
|
||||||
@unmount!
|
|
||||||
@opts.retry!
|
|
||||||
|
|
|
@ -1,25 +1,29 @@
|
||||||
mk-ellipsis
|
<mk-ellipsis><span>.</span><span>.</span><span>.</span>
|
||||||
span .
|
<style type="stylus">
|
||||||
span .
|
:scope
|
||||||
span .
|
display inline
|
||||||
|
|
||||||
style.
|
> span
|
||||||
display inline
|
animation ellipsis 1.4s infinite ease-in-out both
|
||||||
|
|
||||||
> span
|
&:nth-child(1)
|
||||||
animation ellipsis 1.4s infinite ease-in-out both
|
animation-delay 0s
|
||||||
|
|
||||||
&:nth-child(1)
|
&:nth-child(2)
|
||||||
animation-delay 0s
|
animation-delay 0.16s
|
||||||
|
|
||||||
&:nth-child(2)
|
&:nth-child(3)
|
||||||
animation-delay 0.16s
|
animation-delay 0.32s
|
||||||
|
|
||||||
&:nth-child(3)
|
@keyframes ellipsis
|
||||||
animation-delay 0.32s
|
0%, 80%, 100%
|
||||||
|
opacity 1
|
||||||
|
40%
|
||||||
|
opacity 0
|
||||||
|
|
||||||
@keyframes ellipsis
|
|
||||||
0%, 80%, 100%
|
|
||||||
opacity 1
|
|
||||||
40%
|
|
||||||
opacity 0
|
</style>
|
||||||
|
</mk-ellipsis>
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
mk-file-type-icon
|
<mk-file-type-icon><i class="fa fa-file-image-o" if="{ kind == 'image' }"></i>
|
||||||
i.fa.fa-file-image-o(if={ kind == 'image' })
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display inline
|
||||||
|
|
||||||
style.
|
</style>
|
||||||
display inline
|
<script>
|
||||||
|
@file = @opts.file
|
||||||
script.
|
@kind = @file.type.split \/ .0
|
||||||
@file = @opts.file
|
</script>
|
||||||
@kind = @file.type.split \/ .0
|
</mk-file-type-icon>
|
||||||
|
|
|
@ -1,37 +1,44 @@
|
||||||
mk-forkit
|
<mk-forkit><a href="https://github.com/syuilo/misskey" target="_blank" title="View source on Github" aria-label="View source on Github">
|
||||||
a(href='https://github.com/syuilo/misskey', target='_blank', title='View source on Github', aria-label='View source on Github')
|
<svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="aria-hidden">
|
||||||
svg(width='80', height='80', viewBox='0 0 250 250', aria-hidden)
|
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
||||||
path(d='M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z')
|
<path class="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor"></path>
|
||||||
path.octo-arm(d='M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2', fill='currentColor')
|
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor"></path>
|
||||||
path(d='M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z', fill='currentColor')
|
</svg></a>
|
||||||
|
<style type="stylus">
|
||||||
style.
|
:scope
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
|
|
||||||
> a
|
|
||||||
display block
|
|
||||||
|
|
||||||
> svg
|
|
||||||
display block
|
display block
|
||||||
//fill #151513
|
position absolute
|
||||||
//color #fff
|
top 0
|
||||||
fill $theme-color
|
right 0
|
||||||
color $theme-color-foreground
|
|
||||||
|
|
||||||
.octo-arm
|
> a
|
||||||
transform-origin 130px 106px
|
display block
|
||||||
|
|
||||||
&:hover
|
> svg
|
||||||
.octo-arm
|
display block
|
||||||
animation octocat-wave 560ms ease-in-out
|
//fill #151513
|
||||||
|
//color #fff
|
||||||
|
fill $theme-color
|
||||||
|
color $theme-color-foreground
|
||||||
|
|
||||||
@keyframes octocat-wave
|
.octo-arm
|
||||||
0%, 100%
|
transform-origin 130px 106px
|
||||||
transform rotate(0)
|
|
||||||
20%, 60%
|
&:hover
|
||||||
transform rotate(-25deg)
|
.octo-arm
|
||||||
40%, 80%
|
animation octocat-wave 560ms ease-in-out
|
||||||
transform rotate(10deg)
|
|
||||||
|
@keyframes octocat-wave
|
||||||
|
0%, 100%
|
||||||
|
transform rotate(0)
|
||||||
|
20%, 60%
|
||||||
|
transform rotate(-25deg)
|
||||||
|
40%, 80%
|
||||||
|
transform rotate(10deg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</mk-forkit>
|
||||||
|
|
|
@ -1,22 +1,29 @@
|
||||||
mk-introduction
|
<mk-introduction>
|
||||||
article
|
<article>
|
||||||
h1 Misskeyとは?
|
<h1>Misskeyとは?</h1><p><ruby>Misskey<rt>みすきー</rt></ruby>は、<a href="http://syuilo.com" target="_blank">syuilo</a>が2014年くらいから<a href="https://github.com/syuilo/misskey" target="_blank">オープンソースで</a>開発・運営を行っている、ミニブログベースのSNSです。</p>
|
||||||
<p><ruby>Misskey<rt>みすきー</rt></ruby>は、<a href="http://syuilo.com" target="_blank">syuilo</a>が2014年くらいから<a href="https://github.com/syuilo/misskey" target="_blank">オープンソースで</a>開発・運営を行っている、ミニブログベースのSNSです。</p>
|
<p>Twitter, Facebook, LINE, Google+ などを<del>パクって</del><i>参考にして</i>います。</p>
|
||||||
<p>Twitter, Facebook, LINE, Google+ などを<del>パクって</del><i>参考にして</i>います。</p>
|
<p>無料で誰でも利用でき、広告は一切掲載していません。</p>
|
||||||
<p>無料で誰でも利用でき、広告は一切掲載していません。</p>
|
<p><a href="{ CONFIG.urls.about }" target="_blank">もっと知りたい方はこちら</a></p>
|
||||||
<p><a href={ CONFIG.urls.about } target="_blank">もっと知りたい方はこちら</a></p>
|
</article>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
h1
|
||||||
display block
|
margin 0
|
||||||
|
text-align center
|
||||||
|
font-size 1.2em
|
||||||
|
|
||||||
h1
|
p
|
||||||
margin 0
|
margin 16px 0
|
||||||
text-align center
|
|
||||||
font-size 1.2em
|
|
||||||
|
|
||||||
p
|
&:last-child
|
||||||
margin 16px 0
|
margin 0
|
||||||
|
text-align center
|
||||||
|
|
||||||
&:last-child
|
|
||||||
margin 0
|
|
||||||
text-align center
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</mk-introduction>
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
mk-number
|
<mk-number>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display inline
|
||||||
|
|
||||||
style.
|
</style>
|
||||||
display inline
|
<script>
|
||||||
|
@on \mount ~>
|
||||||
|
# バグ? https://github.com/riot/riot/issues/2103
|
||||||
|
#value = @opts.value
|
||||||
|
value = @opts.riot-value
|
||||||
|
max = @opts.max
|
||||||
|
|
||||||
script.
|
if max? then if value > max then value = max
|
||||||
@on \mount ~>
|
|
||||||
# バグ? https://github.com/riot/riot/issues/2103
|
|
||||||
#value = @opts.value
|
|
||||||
value = @opts.riot-value
|
|
||||||
max = @opts.max
|
|
||||||
|
|
||||||
if max? then if value > max then value = max
|
@root.innerHTML = value.to-locale-string!
|
||||||
|
</script>
|
||||||
@root.innerHTML = value.to-locale-string!
|
</mk-number>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
mk-raw
|
<mk-raw>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display inline
|
||||||
|
|
||||||
style.
|
</style>
|
||||||
display inline
|
<script>@root.innerHTML = @opts.content</script>
|
||||||
|
</mk-raw>
|
||||||
script.
|
|
||||||
@root.innerHTML = @opts.content
|
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
mk-ripple-string
|
<mk-ripple-string><yield/>
|
||||||
<yield/>
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display inline
|
||||||
|
|
||||||
style.
|
> span
|
||||||
display inline
|
animation ripple-string 5s infinite ease-in-out both
|
||||||
|
|
||||||
> span
|
@keyframes ripple-string
|
||||||
animation ripple-string 5s infinite ease-in-out both
|
0%, 50%, 100%
|
||||||
|
opacity 1
|
||||||
|
25%
|
||||||
|
opacity 0.5
|
||||||
|
|
||||||
@keyframes ripple-string
|
</style>
|
||||||
0%, 50%, 100%
|
<script>
|
||||||
opacity 1
|
@on \mount ~>
|
||||||
25%
|
text = @root.innerHTML
|
||||||
opacity 0.5
|
@root.innerHTML = ''
|
||||||
|
(text.split '').for-each (c, i) ~>
|
||||||
script.
|
ce = document.create-element \span
|
||||||
@on \mount ~>
|
ce.innerHTML = c
|
||||||
text = @root.innerHTML
|
ce.style.animation-delay = (i / 10) + 's'
|
||||||
@root.innerHTML = ''
|
@root.append-child ce
|
||||||
(text.split '').for-each (c, i) ~>
|
</script>
|
||||||
ce = document.create-element \span
|
</mk-ripple-string>
|
||||||
ce.innerHTML = c
|
|
||||||
ce.style.animation-delay = (i / 10) + 's'
|
|
||||||
@root.append-child ce
|
|
||||||
|
|
|
@ -1,136 +1,131 @@
|
||||||
mk-signin
|
<mk-signin>
|
||||||
form(onsubmit={ onsubmit }, class={ signing: signing })
|
<form class="{ signing: signing }" onsubmit="{ onsubmit }">
|
||||||
label.user-name
|
<label class="user-name">
|
||||||
input@username(
|
<input ref="username" type="text" pattern="^[a-zA-Z0-9-]+$" placeholder="ユーザー名" autofocus="autofocus" required="required" oninput="{ oninput }"/><i class="fa fa-at"></i>
|
||||||
type='text'
|
</label>
|
||||||
pattern='^[a-zA-Z0-9\-]+$'
|
<label class="password">
|
||||||
placeholder='ユーザー名'
|
<input ref="password" type="password" placeholder="パスワード" required="required"/><i class="fa fa-lock"></i>
|
||||||
autofocus
|
</label>
|
||||||
required
|
<button type="submit" disabled="{ signing }">{ signing ? 'やっています...' : 'サインイン' }</button>
|
||||||
oninput={ oninput })
|
</form>
|
||||||
i.fa.fa-at
|
<style type="stylus">
|
||||||
label.password
|
:scope
|
||||||
input@password(
|
|
||||||
type='password'
|
|
||||||
placeholder='パスワード'
|
|
||||||
required)
|
|
||||||
i.fa.fa-lock
|
|
||||||
button(type='submit', disabled={ signing }) { signing ? 'やっています...' : 'サインイン' }
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
|
|
||||||
> form
|
|
||||||
display block
|
|
||||||
z-index 2
|
|
||||||
|
|
||||||
&.signing
|
|
||||||
&, *
|
|
||||||
cursor wait !important
|
|
||||||
|
|
||||||
label
|
|
||||||
display block
|
display block
|
||||||
margin 12px 0
|
|
||||||
|
|
||||||
i
|
> form
|
||||||
display block
|
display block
|
||||||
pointer-events none
|
z-index 2
|
||||||
position absolute
|
|
||||||
bottom 0
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
z-index 1
|
|
||||||
margin auto
|
|
||||||
padding 0 16px
|
|
||||||
height 1em
|
|
||||||
color #898786
|
|
||||||
|
|
||||||
input[type=text]
|
&.signing
|
||||||
input[type=password]
|
&, *
|
||||||
user-select text
|
cursor wait !important
|
||||||
display inline-block
|
|
||||||
cursor auto
|
|
||||||
padding 0 0 0 38px
|
|
||||||
margin 0
|
|
||||||
width 100%
|
|
||||||
line-height 44px
|
|
||||||
font-size 1em
|
|
||||||
color rgba(0, 0, 0, 0.7)
|
|
||||||
background #fff
|
|
||||||
outline none
|
|
||||||
border solid 1px #eee
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:hover
|
label
|
||||||
background rgba(255, 255, 255, 0.7)
|
display block
|
||||||
border-color #ddd
|
margin 12px 0
|
||||||
|
|
||||||
& + i
|
i
|
||||||
color #797776
|
display block
|
||||||
|
pointer-events none
|
||||||
|
position absolute
|
||||||
|
bottom 0
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
z-index 1
|
||||||
|
margin auto
|
||||||
|
padding 0 16px
|
||||||
|
height 1em
|
||||||
|
color #898786
|
||||||
|
|
||||||
&:focus
|
input[type=text]
|
||||||
background #fff
|
input[type=password]
|
||||||
border-color #ccc
|
user-select text
|
||||||
|
display inline-block
|
||||||
|
cursor auto
|
||||||
|
padding 0 0 0 38px
|
||||||
|
margin 0
|
||||||
|
width 100%
|
||||||
|
line-height 44px
|
||||||
|
font-size 1em
|
||||||
|
color rgba(0, 0, 0, 0.7)
|
||||||
|
background #fff
|
||||||
|
outline none
|
||||||
|
border solid 1px #eee
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
& + i
|
&:hover
|
||||||
color #797776
|
background rgba(255, 255, 255, 0.7)
|
||||||
|
border-color #ddd
|
||||||
|
|
||||||
[type=submit]
|
& + i
|
||||||
cursor pointer
|
color #797776
|
||||||
padding 16px
|
|
||||||
margin -6px 0 0 0
|
|
||||||
width 100%
|
|
||||||
font-size 1.2em
|
|
||||||
color rgba(0, 0, 0, 0.5)
|
|
||||||
outline none
|
|
||||||
border none
|
|
||||||
border-radius 0
|
|
||||||
background transparent
|
|
||||||
transition all .5s ease
|
|
||||||
|
|
||||||
&:hover
|
&:focus
|
||||||
color $theme-color
|
background #fff
|
||||||
transition all .2s ease
|
border-color #ccc
|
||||||
|
|
||||||
&:focus
|
& + i
|
||||||
color $theme-color
|
color #797776
|
||||||
transition all .2s ease
|
|
||||||
|
|
||||||
&:active
|
[type=submit]
|
||||||
color darken($theme-color, 30%)
|
cursor pointer
|
||||||
transition all .2s ease
|
padding 16px
|
||||||
|
margin -6px 0 0 0
|
||||||
|
width 100%
|
||||||
|
font-size 1.2em
|
||||||
|
color rgba(0, 0, 0, 0.5)
|
||||||
|
outline none
|
||||||
|
border none
|
||||||
|
border-radius 0
|
||||||
|
background transparent
|
||||||
|
transition all .5s ease
|
||||||
|
|
||||||
&:disabled
|
&:hover
|
||||||
opacity 0.7
|
color $theme-color
|
||||||
|
transition all .2s ease
|
||||||
|
|
||||||
script.
|
&:focus
|
||||||
@mixin \api
|
color $theme-color
|
||||||
|
transition all .2s ease
|
||||||
|
|
||||||
@user = null
|
&:active
|
||||||
@signing = false
|
color darken($theme-color, 30%)
|
||||||
|
transition all .2s ease
|
||||||
|
|
||||||
@oninput = ~>
|
&:disabled
|
||||||
@api \users/show do
|
opacity 0.7
|
||||||
username: @refs.username.value
|
|
||||||
.then (user) ~>
|
</style>
|
||||||
@user = user
|
<script>
|
||||||
@trigger \user user
|
@mixin \api
|
||||||
|
|
||||||
|
@user = null
|
||||||
|
@signing = false
|
||||||
|
|
||||||
|
@oninput = ~>
|
||||||
|
@api \users/show do
|
||||||
|
username: @refs.username.value
|
||||||
|
.then (user) ~>
|
||||||
|
@user = user
|
||||||
|
@trigger \user user
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@onsubmit = (e) ~>
|
||||||
|
e.prevent-default!
|
||||||
|
|
||||||
|
@signing = true
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
@onsubmit = (e) ~>
|
@api \signin do
|
||||||
e.prevent-default!
|
username: @refs.username.value
|
||||||
|
password: @refs.password.value
|
||||||
|
.then ~>
|
||||||
|
location.reload!
|
||||||
|
.catch ~>
|
||||||
|
alert 'something happened'
|
||||||
|
@signing = false
|
||||||
|
@update!
|
||||||
|
|
||||||
@signing = true
|
false
|
||||||
@update!
|
</script>
|
||||||
|
</mk-signin>
|
||||||
@api \signin do
|
|
||||||
username: @refs.username.value
|
|
||||||
password: @refs.password.value
|
|
||||||
.then ~>
|
|
||||||
location.reload!
|
|
||||||
.catch ~>
|
|
||||||
alert 'something happened'
|
|
||||||
@signing = false
|
|
||||||
@update!
|
|
||||||
|
|
||||||
false
|
|
||||||
|
|
|
@ -1,352 +1,293 @@
|
||||||
mk-signup
|
<mk-signup>
|
||||||
form(onsubmit={ onsubmit }, autocomplete='off')
|
<form onsubmit="{ onsubmit }" autocomplete="off">
|
||||||
label.username
|
<label class="username">
|
||||||
p.caption
|
<p class="caption"><i class="fa fa-at"></i>ユーザー名</p>
|
||||||
i.fa.fa-at
|
<input ref="username" type="text" pattern="^[a-zA-Z0-9-]{3,20}$" placeholder="a~z、A~Z、0~9、-" autocomplete="off" required="required" onkeyup="{ onChangeUsername }"/>
|
||||||
| ユーザー名
|
<p class="profile-page-url-preview" if="{ refs.username.value != '' && username-state != 'invalidFormat' && username-state != 'minRange' && username-state != 'maxRange' }">{ CONFIG.url + '/' + refs.username.value }</p>
|
||||||
input@username(
|
<p class="info" if="{ usernameState == 'wait' }" style="color:#999"><i class="fa fa-fw fa-spinner fa-pulse"></i>確認しています...</p>
|
||||||
type='text'
|
<p class="info" if="{ usernameState == 'ok' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>利用できます</p>
|
||||||
pattern='^[a-zA-Z0-9\-]{3,20}$'
|
<p class="info" if="{ usernameState == 'unavailable' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>既に利用されています</p>
|
||||||
placeholder='a~z、A~Z、0~9、-'
|
<p class="info" if="{ usernameState == 'error' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>通信エラー</p>
|
||||||
autocomplete='off'
|
<p class="info" if="{ usernameState == 'invalid-format' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>a~z、A~Z、0~9、-(ハイフン)が使えます</p>
|
||||||
required
|
<p class="info" if="{ usernameState == 'min-range' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>3文字以上でお願いします!</p>
|
||||||
onkeyup={ on-change-username })
|
<p class="info" if="{ usernameState == 'max-range' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>20文字以内でお願いします</p>
|
||||||
|
</label>
|
||||||
p.profile-page-url-preview(if={ refs.username.value != '' && username-state != 'invalid-format' && username-state != 'min-range' && username-state != 'max-range' }) { CONFIG.url + '/' + refs.username.value }
|
<label class="password">
|
||||||
|
<p class="caption"><i class="fa fa-lock"></i>パスワード</p>
|
||||||
p.info(if={ username-state == 'wait' }, style='color:#999')
|
<input ref="password" type="password" placeholder="8文字以上を推奨します" autocomplete="off" required="required" onkeyup="{ onChangePassword }"/>
|
||||||
i.fa.fa-fw.fa-spinner.fa-pulse
|
<div class="meter" if="{ passwordStrength != '' }" data-strength="{ passwordStrength }">
|
||||||
| 確認しています...
|
<div class="value" ref="passwordMetar"></div>
|
||||||
p.info(if={ username-state == 'ok' }, style='color:#3CB7B5')
|
</div>
|
||||||
i.fa.fa-fw.fa-check
|
<p class="info" if="{ passwordStrength == 'low' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>弱いパスワード</p>
|
||||||
| 利用できます
|
<p class="info" if="{ passwordStrength == 'medium' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>まあまあのパスワード</p>
|
||||||
p.info(if={ username-state == 'unavailable' }, style='color:#FF1161')
|
<p class="info" if="{ passwordStrength == 'high' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>強いパスワード</p>
|
||||||
i.fa.fa-fw.fa-exclamation-triangle
|
</label>
|
||||||
| 既に利用されています
|
<label class="retype-password">
|
||||||
p.info(if={ username-state == 'error' }, style='color:#FF1161')
|
<p class="caption"><i class="fa fa-lock"></i>パスワード(再入力)</p>
|
||||||
i.fa.fa-fw.fa-exclamation-triangle
|
<input ref="passwordRetype" type="password" placeholder="確認のため再入力してください" autocomplete="off" required="required" onkeyup="{ onChangePasswordRetype }"/>
|
||||||
| 通信エラー
|
<p class="info" if="{ passwordRetypeState == 'match' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>確認されました</p>
|
||||||
p.info(if={ username-state == 'invalid-format' }, style='color:#FF1161')
|
<p class="info" if="{ passwordRetypeState == 'not-match' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>一致していません</p>
|
||||||
i.fa.fa-fw.fa-exclamation-triangle
|
</label>
|
||||||
| a~z、A~Z、0~9、-(ハイフン)が使えます
|
<label class="recaptcha">
|
||||||
p.info(if={ username-state == 'min-range' }, style='color:#FF1161')
|
<p class="caption"><i class="fa fa-toggle-on" if="{ recaptchaed }"></i><i class="fa fa-toggle-off" if="{ !recaptchaed }"></i>認証</p>
|
||||||
i.fa.fa-fw.fa-exclamation-triangle
|
<div class="g-recaptcha" data-callback="onRecaptchaed" data-expired-callback="onRecaptchaExpired" data-sitekey="{ CONFIG.recaptcha.siteKey }"></div>
|
||||||
| 3文字以上でお願いします!
|
</label>
|
||||||
p.info(if={ username-state == 'max-range' }, style='color:#FF1161')
|
<label class="agree-tou">
|
||||||
i.fa.fa-fw.fa-exclamation-triangle
|
<input name="agree-tou" type="checkbox" autocomplete="off" required="required"/>
|
||||||
| 20文字以内でお願いします
|
<p><a href="{ CONFIG.urls.about + '/tou' }" target="_blank">利用規約</a>に同意する</p>
|
||||||
|
</label>
|
||||||
label.password
|
<button onclick="{ onsubmit }">アカウント作成</button>
|
||||||
p.caption
|
</form>
|
||||||
i.fa.fa-lock
|
<style type="stylus">
|
||||||
| パスワード
|
:scope
|
||||||
input@password(
|
|
||||||
type='password'
|
|
||||||
placeholder='8文字以上を推奨します'
|
|
||||||
autocomplete='off'
|
|
||||||
required
|
|
||||||
onkeyup={ on-change-password })
|
|
||||||
|
|
||||||
div.meter(if={ password-strength != '' }, data-strength={ password-strength })
|
|
||||||
div.value@password-metar
|
|
||||||
|
|
||||||
p.info(if={ password-strength == 'low' }, style='color:#FF1161')
|
|
||||||
i.fa.fa-fw.fa-exclamation-triangle
|
|
||||||
| 弱いパスワード
|
|
||||||
p.info(if={ password-strength == 'medium' }, style='color:#3CB7B5')
|
|
||||||
i.fa.fa-fw.fa-check
|
|
||||||
| まあまあのパスワード
|
|
||||||
p.info(if={ password-strength == 'high' }, style='color:#3CB7B5')
|
|
||||||
i.fa.fa-fw.fa-check
|
|
||||||
| 強いパスワード
|
|
||||||
|
|
||||||
label.retype-password
|
|
||||||
p.caption
|
|
||||||
i.fa.fa-lock
|
|
||||||
| パスワード(再入力)
|
|
||||||
input@password-retype(
|
|
||||||
type='password'
|
|
||||||
placeholder='確認のため再入力してください'
|
|
||||||
autocomplete='off'
|
|
||||||
required
|
|
||||||
onkeyup={ on-change-password-retype })
|
|
||||||
|
|
||||||
p.info(if={ password-retype-state == 'match' }, style='color:#3CB7B5')
|
|
||||||
i.fa.fa-fw.fa-check
|
|
||||||
| 確認されました
|
|
||||||
p.info(if={ password-retype-state == 'not-match' }, style='color:#FF1161')
|
|
||||||
i.fa.fa-fw.fa-exclamation-triangle
|
|
||||||
| 一致していません
|
|
||||||
|
|
||||||
label.recaptcha
|
|
||||||
p.caption
|
|
||||||
i.fa.fa-toggle-on(if={ recaptchaed })
|
|
||||||
i.fa.fa-toggle-off(if={ !recaptchaed })
|
|
||||||
| 認証
|
|
||||||
div.g-recaptcha(
|
|
||||||
data-callback='onRecaptchaed'
|
|
||||||
data-expired-callback='onRecaptchaExpired'
|
|
||||||
data-sitekey={ CONFIG.recaptcha.site-key })
|
|
||||||
|
|
||||||
label.agree-tou
|
|
||||||
input(
|
|
||||||
name='agree-tou',
|
|
||||||
type='checkbox',
|
|
||||||
autocomplete='off',
|
|
||||||
required)
|
|
||||||
p
|
|
||||||
a(href={ CONFIG.urls.about + '/tou' }, target='_blank') 利用規約
|
|
||||||
| に同意する
|
|
||||||
|
|
||||||
button(onclick={ onsubmit })
|
|
||||||
| アカウント作成
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
min-width 302px
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
> form
|
|
||||||
|
|
||||||
label
|
|
||||||
display block
|
display block
|
||||||
margin 16px 0
|
min-width 302px
|
||||||
|
overflow hidden
|
||||||
|
|
||||||
> .caption
|
> form
|
||||||
margin 0 0 4px 0
|
|
||||||
color #828888
|
|
||||||
font-size 0.95em
|
|
||||||
|
|
||||||
> i
|
label
|
||||||
margin-right 0.25em
|
|
||||||
color #96adac
|
|
||||||
|
|
||||||
> .info
|
|
||||||
display block
|
|
||||||
margin 4px 0
|
|
||||||
font-size 0.8em
|
|
||||||
|
|
||||||
> i
|
|
||||||
margin-right 0.3em
|
|
||||||
|
|
||||||
&.username
|
|
||||||
.profile-page-url-preview
|
|
||||||
display block
|
display block
|
||||||
margin 4px 8px 0 4px
|
margin 16px 0
|
||||||
font-size 0.8em
|
|
||||||
color #888
|
|
||||||
|
|
||||||
&:empty
|
> .caption
|
||||||
display none
|
margin 0 0 4px 0
|
||||||
|
color #828888
|
||||||
|
font-size 0.95em
|
||||||
|
|
||||||
&:not(:empty) + .info
|
> i
|
||||||
margin-top 0
|
margin-right 0.25em
|
||||||
|
color #96adac
|
||||||
|
|
||||||
&.password
|
> .info
|
||||||
.meter
|
|
||||||
display block
|
|
||||||
margin-top 8px
|
|
||||||
width 100%
|
|
||||||
height 8px
|
|
||||||
|
|
||||||
&[data-strength='']
|
|
||||||
display none
|
|
||||||
|
|
||||||
&[data-strength='low']
|
|
||||||
> .value
|
|
||||||
background #d73612
|
|
||||||
|
|
||||||
&[data-strength='medium']
|
|
||||||
> .value
|
|
||||||
background #d7ca12
|
|
||||||
|
|
||||||
&[data-strength='high']
|
|
||||||
> .value
|
|
||||||
background #61bb22
|
|
||||||
|
|
||||||
> .value
|
|
||||||
display block
|
display block
|
||||||
width 0%
|
margin 4px 0
|
||||||
height 100%
|
font-size 0.8em
|
||||||
background transparent
|
|
||||||
border-radius 4px
|
|
||||||
transition all 0.1s ease
|
|
||||||
|
|
||||||
[type=text], [type=password]
|
> i
|
||||||
user-select text
|
margin-right 0.3em
|
||||||
display inline-block
|
|
||||||
cursor auto
|
|
||||||
padding 0 12px
|
|
||||||
margin 0
|
|
||||||
width 100%
|
|
||||||
line-height 44px
|
|
||||||
font-size 1em
|
|
||||||
color #333 !important
|
|
||||||
background #fff !important
|
|
||||||
outline none
|
|
||||||
border solid 1px rgba(0, 0, 0, 0.1)
|
|
||||||
border-radius 4px
|
|
||||||
box-shadow 0 0 0 114514px #fff inset
|
|
||||||
transition all .3s ease
|
|
||||||
|
|
||||||
&:hover
|
&.username
|
||||||
border-color rgba(0, 0, 0, 0.2)
|
.profile-page-url-preview
|
||||||
transition all .1s ease
|
display block
|
||||||
|
margin 4px 8px 0 4px
|
||||||
|
font-size 0.8em
|
||||||
|
color #888
|
||||||
|
|
||||||
&:focus
|
&:empty
|
||||||
color $theme-color !important
|
display none
|
||||||
border-color $theme-color
|
|
||||||
box-shadow 0 0 0 1024px #fff inset, 0 0 0 4px rgba($theme-color, 10%)
|
|
||||||
transition all 0s ease
|
|
||||||
|
|
||||||
&:disabled
|
&:not(:empty) + .info
|
||||||
opacity 0.5
|
margin-top 0
|
||||||
|
|
||||||
.agree-tou
|
&.password
|
||||||
padding 4px
|
.meter
|
||||||
border-radius 4px
|
display block
|
||||||
|
margin-top 8px
|
||||||
|
width 100%
|
||||||
|
height 8px
|
||||||
|
|
||||||
&:hover
|
&[data-strength='']
|
||||||
background #f4f4f4
|
display none
|
||||||
|
|
||||||
&:active
|
&[data-strength='low']
|
||||||
background #eee
|
> .value
|
||||||
|
background #d73612
|
||||||
|
|
||||||
&, *
|
&[data-strength='medium']
|
||||||
cursor pointer
|
> .value
|
||||||
|
background #d7ca12
|
||||||
|
|
||||||
p
|
&[data-strength='high']
|
||||||
display inline
|
> .value
|
||||||
color #555
|
background #61bb22
|
||||||
|
|
||||||
button
|
> .value
|
||||||
margin 0 0 32px 0
|
display block
|
||||||
padding 16px
|
width 0%
|
||||||
width 100%
|
height 100%
|
||||||
font-size 1em
|
background transparent
|
||||||
color #fff
|
border-radius 4px
|
||||||
background $theme-color
|
transition all 0.1s ease
|
||||||
border-radius 3px
|
|
||||||
|
|
||||||
&:hover
|
[type=text], [type=password]
|
||||||
background lighten($theme-color, 5%)
|
user-select text
|
||||||
|
display inline-block
|
||||||
|
cursor auto
|
||||||
|
padding 0 12px
|
||||||
|
margin 0
|
||||||
|
width 100%
|
||||||
|
line-height 44px
|
||||||
|
font-size 1em
|
||||||
|
color #333 !important
|
||||||
|
background #fff !important
|
||||||
|
outline none
|
||||||
|
border solid 1px rgba(0, 0, 0, 0.1)
|
||||||
|
border-radius 4px
|
||||||
|
box-shadow 0 0 0 114514px #fff inset
|
||||||
|
transition all .3s ease
|
||||||
|
|
||||||
&:active
|
&:hover
|
||||||
background darken($theme-color, 5%)
|
border-color rgba(0, 0, 0, 0.2)
|
||||||
|
transition all .1s ease
|
||||||
|
|
||||||
script.
|
&:focus
|
||||||
@mixin \api
|
color $theme-color !important
|
||||||
@mixin \get-password-strength
|
border-color $theme-color
|
||||||
|
box-shadow 0 0 0 1024px #fff inset, 0 0 0 4px rgba($theme-color, 10%)
|
||||||
|
transition all 0s ease
|
||||||
|
|
||||||
@username-state = null
|
&:disabled
|
||||||
@password-strength = ''
|
opacity 0.5
|
||||||
@password-retype-state = null
|
|
||||||
@recaptchaed = false
|
|
||||||
|
|
||||||
window.on-recaptchaed = ~>
|
.agree-tou
|
||||||
@recaptchaed = true
|
padding 4px
|
||||||
@update!
|
border-radius 4px
|
||||||
|
|
||||||
window.on-recaptcha-expired = ~>
|
&:hover
|
||||||
|
background #f4f4f4
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background #eee
|
||||||
|
|
||||||
|
&, *
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
|
p
|
||||||
|
display inline
|
||||||
|
color #555
|
||||||
|
|
||||||
|
button
|
||||||
|
margin 0 0 32px 0
|
||||||
|
padding 16px
|
||||||
|
width 100%
|
||||||
|
font-size 1em
|
||||||
|
color #fff
|
||||||
|
background $theme-color
|
||||||
|
border-radius 3px
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background lighten($theme-color, 5%)
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background darken($theme-color, 5%)
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \get-password-strength
|
||||||
|
|
||||||
|
@username-state = null
|
||||||
|
@password-strength = ''
|
||||||
|
@password-retype-state = null
|
||||||
@recaptchaed = false
|
@recaptchaed = false
|
||||||
@update!
|
|
||||||
|
|
||||||
@on \mount ~>
|
window.on-recaptchaed = ~>
|
||||||
head = (document.get-elements-by-tag-name \head).0
|
@recaptchaed = true
|
||||||
script = document.create-element \script
|
|
||||||
..set-attribute \src \https://www.google.com/recaptcha/api.js
|
|
||||||
head.append-child script
|
|
||||||
|
|
||||||
@on-change-username = ~>
|
|
||||||
username = @refs.username.value
|
|
||||||
|
|
||||||
if username == ''
|
|
||||||
@username-state = null
|
|
||||||
@update!
|
|
||||||
return
|
|
||||||
|
|
||||||
err = switch
|
|
||||||
| not username.match /^[a-zA-Z0-9\-]+$/ => \invalid-format
|
|
||||||
| username.length < 3chars => \min-range
|
|
||||||
| username.length > 20chars => \max-range
|
|
||||||
| _ => null
|
|
||||||
|
|
||||||
if err?
|
|
||||||
@username-state = err
|
|
||||||
@update!
|
|
||||||
else
|
|
||||||
@username-state = \wait
|
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
@api \username/available do
|
window.on-recaptcha-expired = ~>
|
||||||
username: username
|
@recaptchaed = false
|
||||||
.then (result) ~>
|
@update!
|
||||||
if result.available
|
|
||||||
@username-state = \ok
|
@on \mount ~>
|
||||||
else
|
head = (document.get-elements-by-tag-name \head).0
|
||||||
@username-state = \unavailable
|
script = document.create-element \script
|
||||||
|
..set-attribute \src \https://www.google.com/recaptcha/api.js
|
||||||
|
head.append-child script
|
||||||
|
|
||||||
|
@on-change-username = ~>
|
||||||
|
username = @refs.username.value
|
||||||
|
|
||||||
|
if username == ''
|
||||||
|
@username-state = null
|
||||||
@update!
|
@update!
|
||||||
.catch (err) ~>
|
return
|
||||||
@username-state = \error
|
|
||||||
|
err = switch
|
||||||
|
| not username.match /^[a-zA-Z0-9\-]+$/ => \invalid-format
|
||||||
|
| username.length < 3chars => \min-range
|
||||||
|
| username.length > 20chars => \max-range
|
||||||
|
| _ => null
|
||||||
|
|
||||||
|
if err?
|
||||||
|
@username-state = err
|
||||||
|
@update!
|
||||||
|
else
|
||||||
|
@username-state = \wait
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
@on-change-password = ~>
|
@api \username/available do
|
||||||
password = @refs.password.value
|
username: username
|
||||||
|
.then (result) ~>
|
||||||
|
if result.available
|
||||||
|
@username-state = \ok
|
||||||
|
else
|
||||||
|
@username-state = \unavailable
|
||||||
|
@update!
|
||||||
|
.catch (err) ~>
|
||||||
|
@username-state = \error
|
||||||
|
@update!
|
||||||
|
|
||||||
if password == ''
|
@on-change-password = ~>
|
||||||
@password-strength = ''
|
password = @refs.password.value
|
||||||
return
|
|
||||||
|
|
||||||
strength = @get-password-strength password
|
if password == ''
|
||||||
|
@password-strength = ''
|
||||||
|
return
|
||||||
|
|
||||||
if strength > 0.3
|
strength = @get-password-strength password
|
||||||
@password-strength = \medium
|
|
||||||
if strength > 0.7
|
|
||||||
@password-strength = \high
|
|
||||||
else
|
|
||||||
@password-strength = \low
|
|
||||||
|
|
||||||
@update!
|
if strength > 0.3
|
||||||
|
@password-strength = \medium
|
||||||
|
if strength > 0.7
|
||||||
|
@password-strength = \high
|
||||||
|
else
|
||||||
|
@password-strength = \low
|
||||||
|
|
||||||
@refs.password-metar.style.width = (strength * 100) + \%
|
@update!
|
||||||
|
|
||||||
@on-change-password-retype = ~>
|
@refs.password-metar.style.width = (strength * 100) + \%
|
||||||
password = @refs.password.value
|
|
||||||
retyped-password = @refs.password-retype.value
|
|
||||||
|
|
||||||
if retyped-password == ''
|
@on-change-password-retype = ~>
|
||||||
@password-retype-state = null
|
password = @refs.password.value
|
||||||
return
|
retyped-password = @refs.password-retype.value
|
||||||
|
|
||||||
if password == retyped-password
|
if retyped-password == ''
|
||||||
@password-retype-state = \match
|
@password-retype-state = null
|
||||||
else
|
return
|
||||||
@password-retype-state = \not-match
|
|
||||||
|
|
||||||
@onsubmit = (e) ~>
|
if password == retyped-password
|
||||||
e.prevent-default!
|
@password-retype-state = \match
|
||||||
|
else
|
||||||
|
@password-retype-state = \not-match
|
||||||
|
|
||||||
username = @refs.username.value
|
@onsubmit = (e) ~>
|
||||||
password = @refs.password.value
|
e.prevent-default!
|
||||||
|
|
||||||
locker = document.body.append-child document.create-element \mk-locker
|
username = @refs.username.value
|
||||||
|
password = @refs.password.value
|
||||||
|
|
||||||
@api \signup do
|
locker = document.body.append-child document.create-element \mk-locker
|
||||||
username: username
|
|
||||||
password: password
|
@api \signup do
|
||||||
'g-recaptcha-response': grecaptcha.get-response!
|
|
||||||
.then ~>
|
|
||||||
@api \signin do
|
|
||||||
username: username
|
username: username
|
||||||
password: password
|
password: password
|
||||||
|
'g-recaptcha-response': grecaptcha.get-response!
|
||||||
.then ~>
|
.then ~>
|
||||||
location.href = CONFIG.url
|
@api \signin do
|
||||||
.catch ~>
|
username: username
|
||||||
alert '何らかの原因によりアカウントの作成に失敗しました。再度お試しください。'
|
password: password
|
||||||
|
.then ~>
|
||||||
|
location.href = CONFIG.url
|
||||||
|
.catch ~>
|
||||||
|
alert '何らかの原因によりアカウントの作成に失敗しました。再度お試しください。'
|
||||||
|
|
||||||
grecaptcha.reset!
|
grecaptcha.reset!
|
||||||
@recaptchaed = false
|
@recaptchaed = false
|
||||||
|
|
||||||
locker.parent-node.remove-child locker
|
locker.parent-node.remove-child locker
|
||||||
|
|
||||||
false
|
false
|
||||||
|
</script>
|
||||||
|
</mk-signup>
|
||||||
|
|
|
@ -1,24 +1,27 @@
|
||||||
mk-special-message
|
<mk-special-message>
|
||||||
p(if={ m == 1 && d == 1 }) Happy New Year!
|
<p if="{ m == 1 && d == 1 }">Happy New Year! </p>
|
||||||
p(if={ m == 12 && d == 25 }) Merry Christmas!
|
<p if="{ m == 12 && d == 25 }">Merry Christmas!</p>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
&:empty
|
||||||
display block
|
display none
|
||||||
|
|
||||||
&:empty
|
> p
|
||||||
display none
|
margin 0
|
||||||
|
padding 4px
|
||||||
|
text-align center
|
||||||
|
font-size 14px
|
||||||
|
font-weight bold
|
||||||
|
text-transform uppercase
|
||||||
|
color #fff
|
||||||
|
background #ff1036
|
||||||
|
|
||||||
> p
|
</style>
|
||||||
margin 0
|
<script>
|
||||||
padding 4px
|
now = new Date!
|
||||||
text-align center
|
@d = now.get-date!
|
||||||
font-size 14px
|
@m = now.get-month! + 1
|
||||||
font-weight bold
|
</script>
|
||||||
text-transform uppercase
|
</mk-special-message>
|
||||||
color #fff
|
|
||||||
background #ff1036
|
|
||||||
|
|
||||||
script.
|
|
||||||
now = new Date!
|
|
||||||
@d = now.get-date!
|
|
||||||
@m = now.get-month! + 1
|
|
||||||
|
|
|
@ -1,43 +1,41 @@
|
||||||
mk-time
|
<mk-time>
|
||||||
time(datetime={ opts.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>
|
||||||
span(if={ mode == 'relative' }) { relative }
|
<script>
|
||||||
span(if={ mode == 'absolute' }) { absolute }
|
@time = new Date @opts.time
|
||||||
span(if={ mode == 'detail' }) { absolute } ({ relative })
|
@mode = @opts.mode || \relative
|
||||||
|
@tickid = null
|
||||||
|
|
||||||
script.
|
@absolute =
|
||||||
@time = new Date @opts.time
|
@time.get-full-year! + \年 +
|
||||||
@mode = @opts.mode || \relative
|
@time.get-month! + 1 + \月 +
|
||||||
@tickid = null
|
@time.get-date! + \日 +
|
||||||
|
' ' +
|
||||||
|
@time.get-hours! + \時 +
|
||||||
|
@time.get-minutes! + \分
|
||||||
|
|
||||||
@absolute =
|
@on \mount ~>
|
||||||
@time.get-full-year! + \年 +
|
if @mode == \relative or @mode == \detail
|
||||||
@time.get-month! + 1 + \月 +
|
@tick!
|
||||||
@time.get-date! + \日 +
|
@tickid = set-interval @tick, 1000ms
|
||||||
' ' +
|
|
||||||
@time.get-hours! + \時 +
|
|
||||||
@time.get-minutes! + \分
|
|
||||||
|
|
||||||
@on \mount ~>
|
@on \unmount ~>
|
||||||
if @mode == \relative or @mode == \detail
|
if @mode == \relative or @mode == \detail
|
||||||
@tick!
|
clear-interval @tickid
|
||||||
@tickid = set-interval @tick, 1000ms
|
|
||||||
|
|
||||||
@on \unmount ~>
|
@tick = ~>
|
||||||
if @mode == \relative or @mode == \detail
|
now = new Date!
|
||||||
clear-interval @tickid
|
ago = (now - @time) / 1000ms
|
||||||
|
@relative = switch
|
||||||
@tick = ~>
|
| ago >= 31536000s => ~~(ago / 31536000s) + '年前'
|
||||||
now = new Date!
|
| ago >= 2592000s => ~~(ago / 2592000s) + 'ヶ月前'
|
||||||
ago = (now - @time) / 1000ms
|
| ago >= 604800s => ~~(ago / 604800s) + '週間前'
|
||||||
@relative = switch
|
| ago >= 86400s => ~~(ago / 86400s) + '日前'
|
||||||
| ago >= 31536000s => ~~(ago / 31536000s) + '年前'
|
| ago >= 3600s => ~~(ago / 3600s) + '時間前'
|
||||||
| ago >= 2592000s => ~~(ago / 2592000s) + 'ヶ月前'
|
| ago >= 60s => ~~(ago / 60s) + '分前'
|
||||||
| ago >= 604800s => ~~(ago / 604800s) + '週間前'
|
| ago >= 10s => ~~(ago % 60s) + '秒前'
|
||||||
| ago >= 86400s => ~~(ago / 86400s) + '日前'
|
| ago >= 0s => 'たった今'
|
||||||
| ago >= 3600s => ~~(ago / 3600s) + '時間前'
|
| ago < 0s => '未来'
|
||||||
| ago >= 60s => ~~(ago / 60s) + '分前'
|
| _ => 'なぞのじかん'
|
||||||
| ago >= 10s => ~~(ago % 60s) + '秒前'
|
@update!
|
||||||
| ago >= 0s => 'たった今'
|
</script>
|
||||||
| ago < 0s => '未来'
|
</mk-time>
|
||||||
| _ => 'なぞのじかん'
|
|
||||||
@update!
|
|
||||||
|
|
|
@ -1,201 +1,195 @@
|
||||||
mk-uploader
|
<mk-uploader>
|
||||||
ol(if={ uploads.length > 0 })
|
<ol if="{ uploads.length > 0 }">
|
||||||
li(each={ uploads })
|
<li each="{ uploads }">
|
||||||
div.img(style='background-image: url({ img })')
|
<div class="img" style="background-image: url({ img })"></div>
|
||||||
p.name
|
<p class="name"><i class="fa fa-spinner fa-pulse"></i>{ name }</p>
|
||||||
i.fa.fa-spinner.fa-pulse
|
<p class="status"><span class="initing" if="{ progress == undefined }">待機中
|
||||||
| { name }
|
<mk-ellipsis></mk-ellipsis></span><span class="kb" if="{ progress != undefined }">{ String(Math.floor(progress.value / 1024)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') }<i>KB</i> / { String(Math.floor(progress.max / 1024)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') }<i>KB</i></span><span class="percentage" if="{ progress != undefined }">{ Math.floor((progress.value / progress.max) * 100) }</span></p>
|
||||||
p.status
|
<progress if="{ progress != undefined && progress.value != progress.max }" value="{ progress.value }" max="{ progress.max }"></progress>
|
||||||
span.initing(if={ progress == undefined })
|
<div class="progress initing" if="{ progress == undefined }"></div>
|
||||||
| 待機中
|
<div class="progress waiting" if="{ progress != undefined && progress.value == progress.max }"></div>
|
||||||
mk-ellipsis
|
</li>
|
||||||
span.kb(if={ progress != undefined })
|
</ol>
|
||||||
| { String(Math.floor(progress.value / 1024)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') }
|
<style type="stylus">
|
||||||
i KB
|
:scope
|
||||||
= ' / '
|
|
||||||
| { String(Math.floor(progress.max / 1024)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') }
|
|
||||||
i KB
|
|
||||||
span.percentage(if={ progress != undefined }) { Math.floor((progress.value / progress.max) * 100) }
|
|
||||||
progress(if={ progress != undefined && progress.value != progress.max }, value={ progress.value }, max={ progress.max })
|
|
||||||
div.progress.initing(if={ progress == undefined })
|
|
||||||
div.progress.waiting(if={ progress != undefined && progress.value == progress.max })
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
overflow auto
|
|
||||||
|
|
||||||
&:empty
|
|
||||||
display none
|
|
||||||
|
|
||||||
> ol
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
list-style none
|
|
||||||
|
|
||||||
> li
|
|
||||||
display block
|
display block
|
||||||
margin 8px 0 0 0
|
overflow auto
|
||||||
padding 0
|
|
||||||
height 36px
|
|
||||||
box-shadow 0 -1px 0 rgba($theme-color, 0.1)
|
|
||||||
border-top solid 8px transparent
|
|
||||||
|
|
||||||
&:first-child
|
&:empty
|
||||||
margin 0
|
display none
|
||||||
box-shadow none
|
|
||||||
border-top none
|
|
||||||
|
|
||||||
> .img
|
> ol
|
||||||
display block
|
display block
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
width 36px
|
|
||||||
height 36px
|
|
||||||
background-size cover
|
|
||||||
background-position center center
|
|
||||||
|
|
||||||
> .name
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
left 44px
|
|
||||||
margin 0
|
margin 0
|
||||||
padding 0
|
padding 0
|
||||||
max-width 256px
|
list-style none
|
||||||
font-size 0.8em
|
|
||||||
color rgba($theme-color, 0.7)
|
|
||||||
white-space nowrap
|
|
||||||
text-overflow ellipsis
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
> i
|
> li
|
||||||
margin-right 4px
|
display block
|
||||||
|
margin 8px 0 0 0
|
||||||
|
padding 0
|
||||||
|
height 36px
|
||||||
|
box-shadow 0 -1px 0 rgba($theme-color, 0.1)
|
||||||
|
border-top solid 8px transparent
|
||||||
|
|
||||||
> .status
|
&:first-child
|
||||||
display block
|
margin 0
|
||||||
position absolute
|
box-shadow none
|
||||||
top 0
|
border-top none
|
||||||
right 0
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
font-size 0.8em
|
|
||||||
|
|
||||||
> .initing
|
> .img
|
||||||
color rgba($theme-color, 0.5)
|
display block
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
width 36px
|
||||||
|
height 36px
|
||||||
|
background-size cover
|
||||||
|
background-position center center
|
||||||
|
|
||||||
> .kb
|
> .name
|
||||||
color rgba($theme-color, 0.5)
|
display block
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 44px
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
max-width 256px
|
||||||
|
font-size 0.8em
|
||||||
|
color rgba($theme-color, 0.7)
|
||||||
|
white-space nowrap
|
||||||
|
text-overflow ellipsis
|
||||||
|
overflow hidden
|
||||||
|
|
||||||
> .percentage
|
> i
|
||||||
display inline-block
|
margin-right 4px
|
||||||
width 48px
|
|
||||||
text-align right
|
|
||||||
|
|
||||||
color rgba($theme-color, 0.7)
|
> .status
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
right 0
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
font-size 0.8em
|
||||||
|
|
||||||
&:after
|
> .initing
|
||||||
content '%'
|
color rgba($theme-color, 0.5)
|
||||||
|
|
||||||
> progress
|
> .kb
|
||||||
display block
|
color rgba($theme-color, 0.5)
|
||||||
position absolute
|
|
||||||
bottom 0
|
|
||||||
right 0
|
|
||||||
margin 0
|
|
||||||
width calc(100% - 44px)
|
|
||||||
height 8px
|
|
||||||
background transparent
|
|
||||||
border none
|
|
||||||
border-radius 4px
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
&::-webkit-progress-value
|
> .percentage
|
||||||
background $theme-color
|
display inline-block
|
||||||
|
width 48px
|
||||||
|
text-align right
|
||||||
|
|
||||||
&::-webkit-progress-bar
|
color rgba($theme-color, 0.7)
|
||||||
background rgba($theme-color, 0.1)
|
|
||||||
|
|
||||||
> .progress
|
&:after
|
||||||
display block
|
content '%'
|
||||||
position absolute
|
|
||||||
bottom 0
|
|
||||||
right 0
|
|
||||||
margin 0
|
|
||||||
width calc(100% - 44px)
|
|
||||||
height 8px
|
|
||||||
border none
|
|
||||||
border-radius 4px
|
|
||||||
background linear-gradient(
|
|
||||||
45deg,
|
|
||||||
lighten($theme-color, 30%) 25%,
|
|
||||||
$theme-color 25%,
|
|
||||||
$theme-color 50%,
|
|
||||||
lighten($theme-color, 30%) 50%,
|
|
||||||
lighten($theme-color, 30%) 75%,
|
|
||||||
$theme-color 75%,
|
|
||||||
$theme-color
|
|
||||||
)
|
|
||||||
background-size 32px 32px
|
|
||||||
animation bg 1.5s linear infinite
|
|
||||||
|
|
||||||
&.initing
|
> progress
|
||||||
opacity 0.3
|
display block
|
||||||
|
position absolute
|
||||||
|
bottom 0
|
||||||
|
right 0
|
||||||
|
margin 0
|
||||||
|
width calc(100% - 44px)
|
||||||
|
height 8px
|
||||||
|
background transparent
|
||||||
|
border none
|
||||||
|
border-radius 4px
|
||||||
|
overflow hidden
|
||||||
|
|
||||||
@keyframes bg
|
&::-webkit-progress-value
|
||||||
from {background-position: 0 0;}
|
background $theme-color
|
||||||
to {background-position: -64px 32px;}
|
|
||||||
|
|
||||||
script.
|
&::-webkit-progress-bar
|
||||||
@mixin \i
|
background rgba($theme-color, 0.1)
|
||||||
|
|
||||||
@uploads = []
|
> .progress
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
bottom 0
|
||||||
|
right 0
|
||||||
|
margin 0
|
||||||
|
width calc(100% - 44px)
|
||||||
|
height 8px
|
||||||
|
border none
|
||||||
|
border-radius 4px
|
||||||
|
background linear-gradient(
|
||||||
|
45deg,
|
||||||
|
lighten($theme-color, 30%) 25%,
|
||||||
|
$theme-color 25%,
|
||||||
|
$theme-color 50%,
|
||||||
|
lighten($theme-color, 30%) 50%,
|
||||||
|
lighten($theme-color, 30%) 75%,
|
||||||
|
$theme-color 75%,
|
||||||
|
$theme-color
|
||||||
|
)
|
||||||
|
background-size 32px 32px
|
||||||
|
animation bg 1.5s linear infinite
|
||||||
|
|
||||||
|
&.initing
|
||||||
|
opacity 0.3
|
||||||
|
|
||||||
|
@keyframes bg
|
||||||
|
from {background-position: 0 0;}
|
||||||
|
to {background-position: -64px 32px;}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
|
||||||
|
@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
|
|
||||||
@update!
|
|
||||||
|
|
||||||
reader = new FileReader!
|
|
||||||
reader.onload = (e) ~>
|
|
||||||
ctx.img = e.target.result
|
|
||||||
@update!
|
|
||||||
reader.read-as-data-URL file
|
|
||||||
|
|
||||||
data = new FormData!
|
|
||||||
data.append \i @I.token
|
|
||||||
data.append \file file
|
|
||||||
|
|
||||||
if folder?
|
|
||||||
data.append \folder_id folder
|
|
||||||
|
|
||||||
xhr = new XMLHttpRequest!
|
|
||||||
xhr.open \POST CONFIG.api.url + '/drive/files/create' true
|
|
||||||
xhr.onload = (e) ~>
|
|
||||||
drive-file = JSON.parse e.target.response
|
|
||||||
|
|
||||||
@trigger \uploaded drive-file
|
|
||||||
|
|
||||||
@uploads = @uploads.filter (x) -> x.id != id
|
|
||||||
@trigger \change-uploads @uploads
|
@trigger \change-uploads @uploads
|
||||||
|
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
xhr.upload.onprogress = (e) ~>
|
reader = new FileReader!
|
||||||
if e.length-computable
|
reader.onload = (e) ~>
|
||||||
if ctx.progress == undefined
|
ctx.img = e.target.result
|
||||||
ctx.progress = {}
|
@update!
|
||||||
ctx.progress.max = e.total
|
reader.read-as-data-URL file
|
||||||
ctx.progress.value = e.loaded
|
|
||||||
|
data = new FormData!
|
||||||
|
data.append \i @I.token
|
||||||
|
data.append \file file
|
||||||
|
|
||||||
|
if folder?
|
||||||
|
data.append \folder_id folder
|
||||||
|
|
||||||
|
xhr = new XMLHttpRequest!
|
||||||
|
xhr.open \POST CONFIG.api.url + '/drive/files/create' true
|
||||||
|
xhr.onload = (e) ~>
|
||||||
|
drive-file = JSON.parse e.target.response
|
||||||
|
|
||||||
|
@trigger \uploaded drive-file
|
||||||
|
|
||||||
|
@uploads = @uploads.filter (x) -> x.id != id
|
||||||
|
@trigger \change-uploads @uploads
|
||||||
|
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
xhr.send data
|
xhr.upload.onprogress = (e) ~>
|
||||||
|
if e.length-computable
|
||||||
|
if ctx.progress == undefined
|
||||||
|
ctx.progress = {}
|
||||||
|
ctx.progress.max = e.total
|
||||||
|
ctx.progress.value = e.loaded
|
||||||
|
@update!
|
||||||
|
|
||||||
|
xhr.send data
|
||||||
|
</script>
|
||||||
|
</mk-uploader>
|
||||||
|
|
|
@ -1,105 +1,110 @@
|
||||||
mk-url-preview
|
<mk-url-preview><a href="{ url }" target="_blank" title="{ url }" if="{ !loading }">
|
||||||
a(href={ url }, target='_blank', title={ url }, if={ !loading })
|
<div class="thumbnail" if="{ thumbnail }" style="{ 'background-image: url(' + thumbnail + ')' }"></div>
|
||||||
div.thumbnail(if={ thumbnail }, style={ 'background-image: url(' + thumbnail + ')' })
|
<article>
|
||||||
article
|
<header>
|
||||||
header: h1 { title }
|
<h1>{ title }</h1>
|
||||||
p { description }
|
</header>
|
||||||
footer
|
<p>{ description }</p>
|
||||||
img.icon(if={ icon }, src={ icon })
|
<footer><img class="icon" if="{ icon }" src="{ icon }"/>
|
||||||
p { sitename }
|
<p>{ sitename }</p>
|
||||||
|
</footer>
|
||||||
|
</article></a>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
font-size 16px
|
||||||
|
|
||||||
style.
|
> a
|
||||||
display block
|
display block
|
||||||
font-size 16px
|
border solid 1px #eee
|
||||||
|
border-radius 4px
|
||||||
|
overflow hidden
|
||||||
|
|
||||||
> a
|
&:hover
|
||||||
display block
|
text-decoration none
|
||||||
border solid 1px #eee
|
border-color #ddd
|
||||||
border-radius 4px
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
&:hover
|
> article > header > h1
|
||||||
text-decoration none
|
text-decoration underline
|
||||||
border-color #ddd
|
|
||||||
|
|
||||||
> article > header > h1
|
> .thumbnail
|
||||||
text-decoration underline
|
position absolute
|
||||||
|
width 100px
|
||||||
|
height 100%
|
||||||
|
background-position center
|
||||||
|
background-size cover
|
||||||
|
|
||||||
> .thumbnail
|
& + article
|
||||||
position absolute
|
left 100px
|
||||||
width 100px
|
width calc(100% - 100px)
|
||||||
height 100%
|
|
||||||
background-position center
|
|
||||||
background-size cover
|
|
||||||
|
|
||||||
& + article
|
> article
|
||||||
left 100px
|
padding 16px
|
||||||
width calc(100% - 100px)
|
|
||||||
|
|
||||||
> article
|
> header
|
||||||
padding 16px
|
margin-bottom 8px
|
||||||
|
|
||||||
> header
|
> h1
|
||||||
margin-bottom 8px
|
margin 0
|
||||||
|
font-size 1em
|
||||||
|
color #555
|
||||||
|
|
||||||
> h1
|
> p
|
||||||
margin 0
|
margin 0
|
||||||
font-size 1em
|
color #777
|
||||||
color #555
|
font-size 0.8em
|
||||||
|
|
||||||
> p
|
> footer
|
||||||
margin 0
|
margin-top 8px
|
||||||
color #777
|
|
||||||
font-size 0.8em
|
|
||||||
|
|
||||||
> footer
|
> img
|
||||||
margin-top 8px
|
display inline-block
|
||||||
|
width 16px
|
||||||
|
heigth 16px
|
||||||
|
margin-right 4px
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
> img
|
> p
|
||||||
display inline-block
|
display inline-block
|
||||||
width 16px
|
margin 0
|
||||||
heigth 16px
|
color #666
|
||||||
margin-right 4px
|
font-size 0.8em
|
||||||
vertical-align bottom
|
line-height 16px
|
||||||
|
|
||||||
> p
|
@media (max-width 500px)
|
||||||
display inline-block
|
font-size 8px
|
||||||
margin 0
|
|
||||||
color #666
|
|
||||||
font-size 0.8em
|
|
||||||
line-height 16px
|
|
||||||
|
|
||||||
@media (max-width 500px)
|
> a
|
||||||
font-size 8px
|
border none
|
||||||
|
|
||||||
> a
|
> .thumbnail
|
||||||
border none
|
width 70px
|
||||||
|
|
||||||
> .thumbnail
|
& + article
|
||||||
width 70px
|
left 70px
|
||||||
|
width calc(100% - 70px)
|
||||||
|
|
||||||
& + article
|
> article
|
||||||
left 70px
|
padding 8px
|
||||||
width calc(100% - 70px)
|
|
||||||
|
|
||||||
> article
|
</style>
|
||||||
padding 8px
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
|
||||||
script.
|
@url = @opts.url
|
||||||
@mixin \api
|
@loading = true
|
||||||
|
|
||||||
@url = @opts.url
|
@on \mount ~>
|
||||||
@loading = true
|
fetch CONFIG.url + '/api:url?url=' + @url
|
||||||
|
.then (res) ~>
|
||||||
|
info <~ res.json!.then
|
||||||
|
@title = info.title
|
||||||
|
@description = info.description
|
||||||
|
@thumbnail = info.thumbnail
|
||||||
|
@icon = info.icon
|
||||||
|
@sitename = info.sitename
|
||||||
|
|
||||||
@on \mount ~>
|
@loading = false
|
||||||
fetch CONFIG.url + '/api:url?url=' + @url
|
@update!
|
||||||
.then (res) ~>
|
</script>
|
||||||
info <~ res.json!.then
|
</mk-url-preview>
|
||||||
@title = info.title
|
|
||||||
@description = info.description
|
|
||||||
@thumbnail = info.thumbnail
|
|
||||||
@icon = info.icon
|
|
||||||
@sitename = info.sitename
|
|
||||||
|
|
||||||
@loading = false
|
|
||||||
@update!
|
|
||||||
|
|
|
@ -1,50 +1,46 @@
|
||||||
mk-url
|
<mk-url><a href="{ url }" target="{ opts.target }"><span class="schema">{ schema }//</span><span class="hostname">{ hostname }</span><span class="port" if="{ port != '' }">:{ port }</span><span class="pathname" if="{ pathname != '' }">{ pathname }</span><span class="query">{ query }</span><span class="hash">{ hash }</span></a>
|
||||||
a(href={ url }, target={ opts.target })
|
<style type="stylus">
|
||||||
span.schema { schema }//
|
:scope
|
||||||
span.hostname { hostname }
|
> a
|
||||||
span.port(if={ port != '' }) :{ port }
|
&:after
|
||||||
span.pathname(if={ pathname != '' }) { pathname }
|
content "\f14c"
|
||||||
span.query { query }
|
display inline-block
|
||||||
span.hash { hash }
|
padding-left 2px
|
||||||
|
font-family FontAwesome
|
||||||
|
font-size .9em
|
||||||
|
font-weight 400
|
||||||
|
font-style normal
|
||||||
|
|
||||||
style.
|
> .schema
|
||||||
> a
|
opacity 0.5
|
||||||
&:after
|
|
||||||
content "\f14c"
|
|
||||||
display inline-block
|
|
||||||
padding-left 2px
|
|
||||||
font-family FontAwesome
|
|
||||||
font-size .9em
|
|
||||||
font-weight 400
|
|
||||||
font-style normal
|
|
||||||
|
|
||||||
> .schema
|
> .hostname
|
||||||
opacity 0.5
|
font-weight bold
|
||||||
|
|
||||||
> .hostname
|
> .pathname
|
||||||
font-weight bold
|
opacity 0.8
|
||||||
|
|
||||||
> .pathname
|
> .query
|
||||||
opacity 0.8
|
opacity 0.5
|
||||||
|
|
||||||
> .query
|
> .hash
|
||||||
opacity 0.5
|
font-style italic
|
||||||
|
|
||||||
> .hash
|
</style>
|
||||||
font-style italic
|
<script>
|
||||||
|
@url = @opts.href
|
||||||
|
|
||||||
script.
|
@on \before-mount ~>
|
||||||
@url = @opts.href
|
parser = document.create-element \a
|
||||||
|
parser.href = @url
|
||||||
|
|
||||||
@on \before-mount ~>
|
@schema = parser.protocol
|
||||||
parser = document.create-element \a
|
@hostname = parser.hostname
|
||||||
parser.href = @url
|
@port = parser.port
|
||||||
|
@pathname = parser.pathname
|
||||||
|
@query = parser.search
|
||||||
|
@hash = parser.hash
|
||||||
|
|
||||||
@schema = parser.protocol
|
@update!
|
||||||
@hostname = parser.hostname
|
</script>
|
||||||
@port = parser.port
|
</mk-url>
|
||||||
@pathname = parser.pathname
|
|
||||||
@query = parser.search
|
|
||||||
@hash = parser.hash
|
|
||||||
|
|
||||||
@update!
|
|
||||||
|
|
|
@ -1,102 +1,105 @@
|
||||||
mk-analog-clock
|
<mk-analog-clock>
|
||||||
canvas@canvas(width='256', height='256')
|
<canvas ref="canvas" width="256" height="256"></canvas>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
> canvas
|
||||||
|
display block
|
||||||
|
width 256px
|
||||||
|
height 256px
|
||||||
|
|
||||||
style.
|
</style>
|
||||||
> canvas
|
<script>
|
||||||
display block
|
@on \mount ~>
|
||||||
width 256px
|
@draw!
|
||||||
height 256px
|
@clock = set-interval @draw, 1000ms
|
||||||
|
|
||||||
script.
|
@on \unmount ~>
|
||||||
@on \mount ~>
|
clear-interval @clock
|
||||||
@draw!
|
|
||||||
@clock = set-interval @draw, 1000ms
|
|
||||||
|
|
||||||
@on \unmount ~>
|
@draw = ~>
|
||||||
clear-interval @clock
|
now = new Date!
|
||||||
|
s = now.get-seconds!
|
||||||
|
m = now.get-minutes!
|
||||||
|
h = now.get-hours!
|
||||||
|
|
||||||
@draw = ~>
|
vec2 = (x, y) ->
|
||||||
now = new Date!
|
@x = x
|
||||||
s = now.get-seconds!
|
@y = y
|
||||||
m = now.get-minutes!
|
|
||||||
h = now.get-hours!
|
|
||||||
|
|
||||||
vec2 = (x, y) ->
|
ctx = @refs.canvas.get-context \2d
|
||||||
@x = x
|
canv-w = @refs.canvas.width
|
||||||
@y = y
|
canv-h = @refs.canvas.height
|
||||||
|
ctx.clear-rect 0, 0, canv-w, canv-h
|
||||||
|
|
||||||
ctx = @refs.canvas.get-context \2d
|
# 背景
|
||||||
canv-w = @refs.canvas.width
|
center = (Math.min (canv-w / 2), (canv-h / 2))
|
||||||
canv-h = @refs.canvas.height
|
line-start = center * 0.90
|
||||||
ctx.clear-rect 0, 0, canv-w, canv-h
|
line-end-short = center * 0.87
|
||||||
|
line-end-long = center * 0.84
|
||||||
|
for i from 0 to 59 by 1
|
||||||
|
angle = Math.PI * i / 30
|
||||||
|
uv = new vec2 (Math.sin angle), (-Math.cos angle)
|
||||||
|
ctx.begin-path!
|
||||||
|
ctx.line-width = 1
|
||||||
|
ctx.move-to do
|
||||||
|
(canv-w / 2) + uv.x * line-start
|
||||||
|
(canv-h / 2) + uv.y * line-start
|
||||||
|
if i % 5 == 0
|
||||||
|
ctx.stroke-style = 'rgba(255, 255, 255, 0.2)'
|
||||||
|
ctx.line-to do
|
||||||
|
(canv-w / 2) + uv.x * line-end-long
|
||||||
|
(canv-h / 2) + uv.y * line-end-long
|
||||||
|
else
|
||||||
|
ctx.stroke-style = 'rgba(255, 255, 255, 0.1)'
|
||||||
|
ctx.line-to do
|
||||||
|
(canv-w / 2) + uv.x * line-end-short
|
||||||
|
(canv-h / 2) + uv.y * line-end-short
|
||||||
|
ctx.stroke!
|
||||||
|
|
||||||
# 背景
|
# 分
|
||||||
center = (Math.min (canv-w / 2), (canv-h / 2))
|
angle = Math.PI * (m + s / 60) / 30
|
||||||
line-start = center * 0.90
|
length = (Math.min canv-w, canv-h) / 2.6
|
||||||
line-end-short = center * 0.87
|
|
||||||
line-end-long = center * 0.84
|
|
||||||
for i from 0 to 59 by 1
|
|
||||||
angle = Math.PI * i / 30
|
|
||||||
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.line-width = 1
|
ctx.stroke-style = \#ffffff
|
||||||
|
ctx.line-width = 2
|
||||||
ctx.move-to do
|
ctx.move-to do
|
||||||
(canv-w / 2) + uv.x * line-start
|
(canv-w / 2) - uv.x * length / 5
|
||||||
(canv-h / 2) + uv.y * line-start
|
(canv-h / 2) - uv.y * length / 5
|
||||||
if i % 5 == 0
|
ctx.line-to do
|
||||||
ctx.stroke-style = 'rgba(255, 255, 255, 0.2)'
|
(canv-w / 2) + uv.x * length
|
||||||
ctx.line-to do
|
(canv-h / 2) + uv.y * length
|
||||||
(canv-w / 2) + uv.x * line-end-long
|
|
||||||
(canv-h / 2) + uv.y * line-end-long
|
|
||||||
else
|
|
||||||
ctx.stroke-style = 'rgba(255, 255, 255, 0.1)'
|
|
||||||
ctx.line-to do
|
|
||||||
(canv-w / 2) + uv.x * 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 * (h % 12 + m / 60) / 6
|
||||||
length = (Math.min canv-w, canv-h) / 2.6
|
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.line-width = 2
|
ctx.stroke-style = CONFIG.theme-color
|
||||||
ctx.move-to do
|
ctx.line-width = 2
|
||||||
(canv-w / 2) - uv.x * length / 5
|
ctx.move-to do
|
||||||
(canv-h / 2) - uv.y * length / 5
|
(canv-w / 2) - uv.x * length / 5
|
||||||
ctx.line-to do
|
(canv-h / 2) - uv.y * length / 5
|
||||||
(canv-w / 2) + uv.x * length
|
ctx.line-to do
|
||||||
(canv-h / 2) + uv.y * length
|
(canv-w / 2) + uv.x * length
|
||||||
ctx.stroke!
|
(canv-h / 2) + uv.y * length
|
||||||
|
ctx.stroke!
|
||||||
|
|
||||||
# 時
|
# 秒
|
||||||
angle = Math.PI * (h % 12 + m / 60) / 6
|
angle = Math.PI * s / 30
|
||||||
length = (Math.min canv-w, canv-h) / 4
|
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 = 'rgba(255, 255, 255, 0.5)'
|
||||||
ctx.stroke-style = CONFIG.theme-color
|
ctx.line-width = 1
|
||||||
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
|
(canv-h / 2) - uv.y * length / 5
|
||||||
(canv-h / 2) - uv.y * length / 5
|
ctx.line-to do
|
||||||
ctx.line-to do
|
(canv-w / 2) + uv.x * length
|
||||||
(canv-w / 2) + uv.x * length
|
(canv-h / 2) + uv.y * length
|
||||||
(canv-h / 2) + uv.y * length
|
ctx.stroke!
|
||||||
ctx.stroke!
|
</script>
|
||||||
|
</mk-analog-clock>
|
||||||
# 秒
|
|
||||||
angle = Math.PI * s / 30
|
|
||||||
length = (Math.min canv-w, canv-h) / 2.6
|
|
||||||
uv = new vec2 (Math.sin angle), (-Math.cos angle)
|
|
||||||
ctx.begin-path!
|
|
||||||
ctx.stroke-style = 'rgba(255, 255, 255, 0.5)'
|
|
||||||
ctx.line-width = 1
|
|
||||||
ctx.move-to do
|
|
||||||
(canv-w / 2) - uv.x * length / 5
|
|
||||||
(canv-h / 2) - uv.y * length / 5
|
|
||||||
ctx.line-to do
|
|
||||||
(canv-w / 2) + uv.x * length
|
|
||||||
(canv-h / 2) + uv.y * length
|
|
||||||
ctx.stroke!
|
|
||||||
|
|
|
@ -1,182 +1,183 @@
|
||||||
mk-autocomplete-suggestion
|
<mk-autocomplete-suggestion>
|
||||||
ol.users@users(if={ users.length > 0 })
|
<ol class="users" ref="users" if="{ users.length > 0 }">
|
||||||
li(each={ users }, onclick={ parent.on-click }, onkeydown={ parent.on-keydown }, tabindex='-1')
|
<li each="{ users }" onclick="{ parent.onClick }" onkeydown="{ parent.onKeydown }" tabindex="-1"><img class="avatar" src="{ avatar_url + '?thumbnail&size=32' }" alt=""/><span class="name">{ name }</span><span class="username">@{ username }</span></li>
|
||||||
img.avatar(src={ avatar_url + '?thumbnail&size=32' }, alt='')
|
</ol>
|
||||||
span.name { name }
|
<style type="stylus">
|
||||||
span.username @{ username }
|
:scope
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
z-index 65535
|
|
||||||
margin-top calc(1em + 8px)
|
|
||||||
overflow hidden
|
|
||||||
background #fff
|
|
||||||
border solid 1px rgba(0, 0, 0, 0.1)
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
> .users
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 4px 0
|
|
||||||
max-height 190px
|
|
||||||
max-width 500px
|
|
||||||
overflow auto
|
|
||||||
list-style none
|
|
||||||
|
|
||||||
> li
|
|
||||||
display block
|
display block
|
||||||
padding 4px 12px
|
position absolute
|
||||||
white-space nowrap
|
z-index 65535
|
||||||
|
margin-top calc(1em + 8px)
|
||||||
overflow hidden
|
overflow hidden
|
||||||
font-size 0.9em
|
background #fff
|
||||||
color rgba(0, 0, 0, 0.8)
|
border solid 1px rgba(0, 0, 0, 0.1)
|
||||||
cursor default
|
border-radius 4px
|
||||||
|
|
||||||
&, *
|
> .users
|
||||||
user-select none
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 4px 0
|
||||||
|
max-height 190px
|
||||||
|
max-width 500px
|
||||||
|
overflow auto
|
||||||
|
list-style none
|
||||||
|
|
||||||
&:hover
|
> li
|
||||||
&[data-selected='true']
|
display block
|
||||||
color #fff
|
padding 4px 12px
|
||||||
background $theme-color
|
white-space nowrap
|
||||||
|
overflow hidden
|
||||||
|
font-size 0.9em
|
||||||
|
color rgba(0, 0, 0, 0.8)
|
||||||
|
cursor default
|
||||||
|
|
||||||
.name
|
&, *
|
||||||
color #fff
|
user-select none
|
||||||
|
|
||||||
.username
|
&:hover
|
||||||
color #fff
|
&[data-selected='true']
|
||||||
|
color #fff
|
||||||
|
background $theme-color
|
||||||
|
|
||||||
&:active
|
.name
|
||||||
color #fff
|
color #fff
|
||||||
background darken($theme-color, 10%)
|
|
||||||
|
|
||||||
.name
|
.username
|
||||||
color #fff
|
color #fff
|
||||||
|
|
||||||
.username
|
&:active
|
||||||
color #fff
|
color #fff
|
||||||
|
background darken($theme-color, 10%)
|
||||||
|
|
||||||
.avatar
|
.name
|
||||||
vertical-align middle
|
color #fff
|
||||||
min-width 28px
|
|
||||||
min-height 28px
|
|
||||||
max-width 28px
|
|
||||||
max-height 28px
|
|
||||||
margin 0 8px 0 0
|
|
||||||
border-radius 100%
|
|
||||||
|
|
||||||
.name
|
.username
|
||||||
margin 0 8px 0 0
|
color #fff
|
||||||
/*font-weight bold*/
|
|
||||||
font-weight normal
|
|
||||||
color rgba(0, 0, 0, 0.8)
|
|
||||||
|
|
||||||
.username
|
.avatar
|
||||||
font-weight normal
|
vertical-align middle
|
||||||
color rgba(0, 0, 0, 0.3)
|
min-width 28px
|
||||||
|
min-height 28px
|
||||||
|
max-width 28px
|
||||||
|
max-height 28px
|
||||||
|
margin 0 8px 0 0
|
||||||
|
border-radius 100%
|
||||||
|
|
||||||
script.
|
.name
|
||||||
@mixin \api
|
margin 0 8px 0 0
|
||||||
|
/*font-weight bold*/
|
||||||
|
font-weight normal
|
||||||
|
color rgba(0, 0, 0, 0.8)
|
||||||
|
|
||||||
@q = @opts.q
|
.username
|
||||||
@textarea = @opts.textarea
|
font-weight normal
|
||||||
@loading = true
|
color rgba(0, 0, 0, 0.3)
|
||||||
@users = []
|
|
||||||
@select = -1
|
|
||||||
|
|
||||||
@on \mount ~>
|
</style>
|
||||||
@textarea.add-event-listener \keydown @on-keydown
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
|
||||||
all = document.query-selector-all 'body *'
|
@q = @opts.q
|
||||||
Array.prototype.for-each.call all, (el) ~>
|
@textarea = @opts.textarea
|
||||||
el.add-event-listener \mousedown @mousedown
|
@loading = true
|
||||||
|
@users = []
|
||||||
|
@select = -1
|
||||||
|
|
||||||
@api \users/search_by_username do
|
@on \mount ~>
|
||||||
query: @q
|
@textarea.add-event-listener \keydown @on-keydown
|
||||||
limit: 30users
|
|
||||||
.then (users) ~>
|
|
||||||
@users = users
|
|
||||||
@loading = false
|
|
||||||
@update!
|
|
||||||
.catch (err) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@on \unmount ~>
|
all = document.query-selector-all 'body *'
|
||||||
@textarea.remove-event-listener \keydown @on-keydown
|
Array.prototype.for-each.call all, (el) ~>
|
||||||
|
el.add-event-listener \mousedown @mousedown
|
||||||
|
|
||||||
all = document.query-selector-all 'body *'
|
@api \users/search_by_username do
|
||||||
Array.prototype.for-each.call all, (el) ~>
|
query: @q
|
||||||
el.remove-event-listener \mousedown @mousedown
|
limit: 30users
|
||||||
|
.then (users) ~>
|
||||||
|
@users = users
|
||||||
|
@loading = false
|
||||||
|
@update!
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
@mousedown = (e) ~>
|
@on \unmount ~>
|
||||||
if (!contains @root, e.target) and (@root != e.target)
|
@textarea.remove-event-listener \keydown @on-keydown
|
||||||
@close!
|
|
||||||
|
|
||||||
@on-click = (e) ~>
|
all = document.query-selector-all 'body *'
|
||||||
@complete e.item
|
Array.prototype.for-each.call all, (el) ~>
|
||||||
|
el.remove-event-listener \mousedown @mousedown
|
||||||
|
|
||||||
@on-keydown = (e) ~>
|
@mousedown = (e) ~>
|
||||||
key = e.which
|
if (!contains @root, e.target) and (@root != e.target)
|
||||||
switch (key)
|
|
||||||
| 10, 13 => # Key[ENTER]
|
|
||||||
if @select != -1
|
|
||||||
e.prevent-default!
|
|
||||||
e.stop-propagation!
|
|
||||||
@complete @users[@select]
|
|
||||||
else
|
|
||||||
@close!
|
|
||||||
| 27 => # Key[ESC]
|
|
||||||
e.prevent-default!
|
|
||||||
e.stop-propagation!
|
|
||||||
@close!
|
|
||||||
| 38 => # Key[↑]
|
|
||||||
if @select != -1
|
|
||||||
e.prevent-default!
|
|
||||||
e.stop-propagation!
|
|
||||||
@select-prev!
|
|
||||||
else
|
|
||||||
@close!
|
|
||||||
| 9, 40 => # Key[TAB] or Key[↓]
|
|
||||||
e.prevent-default!
|
|
||||||
e.stop-propagation!
|
|
||||||
@select-next!
|
|
||||||
| _ =>
|
|
||||||
@close!
|
@close!
|
||||||
|
|
||||||
@select-next = ~>
|
@on-click = (e) ~>
|
||||||
@select++
|
@complete e.item
|
||||||
|
|
||||||
if @select >= @users.length
|
@on-keydown = (e) ~>
|
||||||
@select = 0
|
key = e.which
|
||||||
|
switch (key)
|
||||||
|
| 10, 13 => # Key[ENTER]
|
||||||
|
if @select != -1
|
||||||
|
e.prevent-default!
|
||||||
|
e.stop-propagation!
|
||||||
|
@complete @users[@select]
|
||||||
|
else
|
||||||
|
@close!
|
||||||
|
| 27 => # Key[ESC]
|
||||||
|
e.prevent-default!
|
||||||
|
e.stop-propagation!
|
||||||
|
@close!
|
||||||
|
| 38 => # Key[↑]
|
||||||
|
if @select != -1
|
||||||
|
e.prevent-default!
|
||||||
|
e.stop-propagation!
|
||||||
|
@select-prev!
|
||||||
|
else
|
||||||
|
@close!
|
||||||
|
| 9, 40 => # Key[TAB] or Key[↓]
|
||||||
|
e.prevent-default!
|
||||||
|
e.stop-propagation!
|
||||||
|
@select-next!
|
||||||
|
| _ =>
|
||||||
|
@close!
|
||||||
|
|
||||||
@apply-select!
|
@select-next = ~>
|
||||||
|
@select++
|
||||||
|
|
||||||
@select-prev = ~>
|
if @select >= @users.length
|
||||||
@select--
|
@select = 0
|
||||||
|
|
||||||
if @select < 0
|
@apply-select!
|
||||||
@select = @users.length - 1
|
|
||||||
|
|
||||||
@apply-select!
|
@select-prev = ~>
|
||||||
|
@select--
|
||||||
|
|
||||||
@apply-select = ~>
|
if @select < 0
|
||||||
@refs.users.children.for-each (el) ~>
|
@select = @users.length - 1
|
||||||
el.remove-attribute \data-selected
|
|
||||||
|
|
||||||
@refs.users.children[@select].set-attribute \data-selected \true
|
@apply-select!
|
||||||
@refs.users.children[@select].focus!
|
|
||||||
|
|
||||||
@complete = (user) ~>
|
@apply-select = ~>
|
||||||
@opts.complete user
|
@refs.users.children.for-each (el) ~>
|
||||||
|
el.remove-attribute \data-selected
|
||||||
|
|
||||||
@close = ~>
|
@refs.users.children[@select].set-attribute \data-selected \true
|
||||||
@opts.close!
|
@refs.users.children[@select].focus!
|
||||||
|
|
||||||
function contains(parent, child)
|
@complete = (user) ~>
|
||||||
node = child.parent-node
|
@opts.complete user
|
||||||
while node?
|
|
||||||
if node == parent
|
@close = ~>
|
||||||
return true
|
@opts.close!
|
||||||
node = node.parent-node
|
|
||||||
return false
|
function contains(parent, child)
|
||||||
|
node = child.parent-node
|
||||||
|
while node?
|
||||||
|
if node == parent
|
||||||
|
return true
|
||||||
|
node = node.parent-node
|
||||||
|
return false
|
||||||
|
</script>
|
||||||
|
</mk-autocomplete-suggestion>
|
||||||
|
|
|
@ -1,134 +1,127 @@
|
||||||
mk-big-follow-button
|
<mk-big-follow-button>
|
||||||
button(if={ !init }, class={ wait: wait, follow: !user.is_following, unfollow: user.is_following },
|
<button class="{ wait: wait, follow: !user.is_following, unfollow: user.is_following }" if="{ !init }" onclick="{ onclick }" disabled="{ wait }" title="{ user.is_following ? 'フォロー解除' : 'フォローする' }"><span if="{ !wait && user.is_following }"><i class="fa fa-minus"></i>フォロー解除</span><span if="{ !wait && !user.is_following }"><i class="fa fa-plus"></i>フォロー</span><i class="fa fa-spinner fa-pulse fa-fw" if="{ wait }"></i></button>
|
||||||
onclick={ onclick },
|
<div class="init" if="{ init }"><i class="fa fa-spinner fa-pulse fa-fw"></i></div>
|
||||||
disabled={ wait },
|
<style type="stylus">
|
||||||
title={ user.is_following ? 'フォロー解除' : 'フォローする' })
|
:scope
|
||||||
span(if={ !wait && user.is_following })
|
display block
|
||||||
i.fa.fa-minus
|
|
||||||
| フォロー解除
|
|
||||||
span(if={ !wait && !user.is_following })
|
|
||||||
i.fa.fa-plus
|
|
||||||
| フォロー
|
|
||||||
i.fa.fa-spinner.fa-pulse.fa-fw(if={ wait })
|
|
||||||
div.init(if={ init }): i.fa.fa-spinner.fa-pulse.fa-fw
|
|
||||||
|
|
||||||
style.
|
> button
|
||||||
display block
|
> .init
|
||||||
|
display block
|
||||||
|
cursor pointer
|
||||||
|
padding 0
|
||||||
|
margin 0
|
||||||
|
width 100%
|
||||||
|
line-height 38px
|
||||||
|
font-size 1em
|
||||||
|
outline none
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
> button
|
*
|
||||||
> .init
|
pointer-events none
|
||||||
display block
|
|
||||||
cursor pointer
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
width 100%
|
|
||||||
line-height 38px
|
|
||||||
font-size 1em
|
|
||||||
outline none
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
*
|
i
|
||||||
pointer-events none
|
margin-right 8px
|
||||||
|
|
||||||
i
|
&:focus
|
||||||
margin-right 8px
|
&:after
|
||||||
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
position absolute
|
||||||
|
top -5px
|
||||||
|
right -5px
|
||||||
|
bottom -5px
|
||||||
|
left -5px
|
||||||
|
border 2px solid rgba($theme-color, 0.3)
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
&:focus
|
&.follow
|
||||||
&:after
|
color #888
|
||||||
content ""
|
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
||||||
pointer-events none
|
border solid 1px #e2e2e2
|
||||||
position absolute
|
|
||||||
top -5px
|
|
||||||
right -5px
|
|
||||||
bottom -5px
|
|
||||||
left -5px
|
|
||||||
border 2px solid rgba($theme-color, 0.3)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
&.follow
|
&:hover
|
||||||
color #888
|
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
||||||
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
border-color #dcdcdc
|
||||||
border solid 1px #e2e2e2
|
|
||||||
|
|
||||||
&:hover
|
&:active
|
||||||
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
background #ececec
|
||||||
border-color #dcdcdc
|
border-color #dcdcdc
|
||||||
|
|
||||||
&:active
|
&.unfollow
|
||||||
background #ececec
|
color $theme-color-foreground
|
||||||
border-color #dcdcdc
|
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
||||||
|
border solid 1px lighten($theme-color, 15%)
|
||||||
|
|
||||||
&.unfollow
|
&:not(:disabled)
|
||||||
color $theme-color-foreground
|
font-weight bold
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
|
||||||
border solid 1px lighten($theme-color, 15%)
|
|
||||||
|
|
||||||
&:not(:disabled)
|
&:hover:not(:disabled)
|
||||||
font-weight bold
|
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
||||||
|
border-color $theme-color
|
||||||
|
|
||||||
&:hover:not(:disabled)
|
&:active:not(:disabled)
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
background $theme-color
|
||||||
border-color $theme-color
|
border-color $theme-color
|
||||||
|
|
||||||
&:active:not(:disabled)
|
&.wait
|
||||||
background $theme-color
|
cursor wait !important
|
||||||
border-color $theme-color
|
opacity 0.7
|
||||||
|
|
||||||
&.wait
|
</style>
|
||||||
cursor wait !important
|
<script>
|
||||||
opacity 0.7
|
@mixin \api
|
||||||
|
@mixin \is-promise
|
||||||
|
@mixin \stream
|
||||||
|
|
||||||
script.
|
@user = null
|
||||||
@mixin \api
|
@user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
|
||||||
@mixin \is-promise
|
@init = true
|
||||||
@mixin \stream
|
@wait = false
|
||||||
|
|
||||||
@user = null
|
@on \mount ~>
|
||||||
@user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
|
@user-promise.then (user) ~>
|
||||||
@init = true
|
@user = user
|
||||||
@wait = false
|
@init = false
|
||||||
|
|
||||||
@on \mount ~>
|
|
||||||
@user-promise.then (user) ~>
|
|
||||||
@user = user
|
|
||||||
@init = false
|
|
||||||
@update!
|
|
||||||
@stream.on \follow @on-stream-follow
|
|
||||||
@stream.on \unfollow @on-stream-unfollow
|
|
||||||
|
|
||||||
@on \unmount ~>
|
|
||||||
@stream.off \follow @on-stream-follow
|
|
||||||
@stream.off \unfollow @on-stream-unfollow
|
|
||||||
|
|
||||||
@on-stream-follow = (user) ~>
|
|
||||||
if user.id == @user.id
|
|
||||||
@user = user
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@on-stream-unfollow = (user) ~>
|
|
||||||
if user.id == @user.id
|
|
||||||
@user = user
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@onclick = ~>
|
|
||||||
@wait = true
|
|
||||||
if @user.is_following
|
|
||||||
@api \following/delete do
|
|
||||||
user_id: @user.id
|
|
||||||
.then ~>
|
|
||||||
@user.is_following = false
|
|
||||||
.catch (err) ->
|
|
||||||
console.error err
|
|
||||||
.then ~>
|
|
||||||
@wait = false
|
|
||||||
@update!
|
@update!
|
||||||
else
|
@stream.on \follow @on-stream-follow
|
||||||
@api \following/create do
|
@stream.on \unfollow @on-stream-unfollow
|
||||||
user_id: @user.id
|
|
||||||
.then ~>
|
@on \unmount ~>
|
||||||
@user.is_following = true
|
@stream.off \follow @on-stream-follow
|
||||||
.catch (err) ->
|
@stream.off \unfollow @on-stream-unfollow
|
||||||
console.error err
|
|
||||||
.then ~>
|
@on-stream-follow = (user) ~>
|
||||||
@wait = false
|
if user.id == @user.id
|
||||||
|
@user = user
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
|
@on-stream-unfollow = (user) ~>
|
||||||
|
if user.id == @user.id
|
||||||
|
@user = user
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@onclick = ~>
|
||||||
|
@wait = true
|
||||||
|
if @user.is_following
|
||||||
|
@api \following/delete do
|
||||||
|
user_id: @user.id
|
||||||
|
.then ~>
|
||||||
|
@user.is_following = false
|
||||||
|
.catch (err) ->
|
||||||
|
console.error err
|
||||||
|
.then ~>
|
||||||
|
@wait = false
|
||||||
|
@update!
|
||||||
|
else
|
||||||
|
@api \following/create do
|
||||||
|
user_id: @user.id
|
||||||
|
.then ~>
|
||||||
|
@user.is_following = true
|
||||||
|
.catch (err) ->
|
||||||
|
console.error err
|
||||||
|
.then ~>
|
||||||
|
@wait = false
|
||||||
|
@update!
|
||||||
|
</script>
|
||||||
|
</mk-big-follow-button>
|
||||||
|
|
|
@ -1,138 +1,139 @@
|
||||||
mk-contextmenu
|
<mk-contextmenu><yield />
|
||||||
| <yield />
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
$width = 240px
|
||||||
|
$item-height = 38px
|
||||||
|
$padding = 10px
|
||||||
|
|
||||||
style.
|
display none
|
||||||
$width = 240px
|
position fixed
|
||||||
$item-height = 38px
|
top 0
|
||||||
$padding = 10px
|
left 0
|
||||||
|
z-index 4096
|
||||||
|
width $width
|
||||||
|
font-size 0.8em
|
||||||
|
background #fff
|
||||||
|
border-radius 0 4px 4px 4px
|
||||||
|
box-shadow 2px 2px 8px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
display none
|
ul
|
||||||
position fixed
|
display block
|
||||||
top 0
|
margin 0
|
||||||
left 0
|
padding $padding 0
|
||||||
z-index 4096
|
list-style none
|
||||||
width $width
|
|
||||||
font-size 0.8em
|
|
||||||
background #fff
|
|
||||||
border-radius 0 4px 4px 4px
|
|
||||||
box-shadow 2px 2px 8px rgba(0, 0, 0, 0.2)
|
|
||||||
|
|
||||||
ul
|
li
|
||||||
display block
|
display block
|
||||||
margin 0
|
|
||||||
padding $padding 0
|
|
||||||
list-style none
|
|
||||||
|
|
||||||
li
|
&.separator
|
||||||
display block
|
margin-top $padding
|
||||||
|
padding-top $padding
|
||||||
|
border-top solid 1px #eee
|
||||||
|
|
||||||
&.separator
|
&.has-child
|
||||||
margin-top $padding
|
> p
|
||||||
padding-top $padding
|
cursor default
|
||||||
border-top solid 1px #eee
|
|
||||||
|
|
||||||
&.has-child
|
> i:last-child
|
||||||
> p
|
position absolute
|
||||||
cursor default
|
top 0
|
||||||
|
right 8px
|
||||||
|
line-height $item-height
|
||||||
|
|
||||||
> i:last-child
|
&:hover > ul
|
||||||
position absolute
|
visibility visible
|
||||||
top 0
|
|
||||||
right 8px
|
|
||||||
line-height $item-height
|
|
||||||
|
|
||||||
&:hover > ul
|
&:active
|
||||||
visibility visible
|
> p, a
|
||||||
|
background $theme-color
|
||||||
|
|
||||||
&:active
|
|
||||||
> p, a
|
> p, a
|
||||||
background $theme-color
|
display block
|
||||||
|
z-index 1
|
||||||
|
margin 0
|
||||||
|
padding 0 32px 0 38px
|
||||||
|
line-height $item-height
|
||||||
|
color #868C8C
|
||||||
|
text-decoration none
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
> p, a
|
&:hover
|
||||||
display block
|
text-decoration none
|
||||||
z-index 1
|
|
||||||
margin 0
|
|
||||||
padding 0 32px 0 38px
|
|
||||||
line-height $item-height
|
|
||||||
color #868C8C
|
|
||||||
text-decoration none
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
&:hover
|
*
|
||||||
text-decoration none
|
pointer-events none
|
||||||
|
|
||||||
*
|
> i
|
||||||
pointer-events none
|
width 28px
|
||||||
|
margin-left -28px
|
||||||
|
text-align center
|
||||||
|
|
||||||
> i
|
&:hover
|
||||||
width 28px
|
> p, a
|
||||||
margin-left -28px
|
text-decoration none
|
||||||
text-align center
|
background $theme-color
|
||||||
|
color $theme-color-foreground
|
||||||
|
|
||||||
&:hover
|
&:active
|
||||||
> p, a
|
> p, a
|
||||||
text-decoration none
|
text-decoration none
|
||||||
background $theme-color
|
background darken($theme-color, 10%)
|
||||||
color $theme-color-foreground
|
color $theme-color-foreground
|
||||||
|
|
||||||
&:active
|
li > ul
|
||||||
> p, a
|
visibility hidden
|
||||||
text-decoration none
|
position absolute
|
||||||
background darken($theme-color, 10%)
|
top 0
|
||||||
color $theme-color-foreground
|
left $width
|
||||||
|
margin-top -($padding)
|
||||||
|
width $width
|
||||||
|
background #fff
|
||||||
|
border-radius 0 4px 4px 4px
|
||||||
|
box-shadow 2px 2px 8px rgba(0, 0, 0, 0.2)
|
||||||
|
transition visibility 0s linear 0.2s
|
||||||
|
|
||||||
li > ul
|
</style>
|
||||||
visibility hidden
|
<script>
|
||||||
position absolute
|
@root.add-event-listener \contextmenu (e) ~>
|
||||||
top 0
|
e.prevent-default!
|
||||||
left $width
|
|
||||||
margin-top -($padding)
|
|
||||||
width $width
|
|
||||||
background #fff
|
|
||||||
border-radius 0 4px 4px 4px
|
|
||||||
box-shadow 2px 2px 8px rgba(0, 0, 0, 0.2)
|
|
||||||
transition visibility 0s linear 0.2s
|
|
||||||
|
|
||||||
script.
|
@mousedown = (e) ~>
|
||||||
|
e.prevent-default!
|
||||||
|
if (!contains @root, e.target) and (@root != e.target)
|
||||||
|
@close!
|
||||||
|
return false
|
||||||
|
|
||||||
@root.add-event-listener \contextmenu (e) ~>
|
@open = (pos) ~>
|
||||||
e.prevent-default!
|
all = document.query-selector-all 'body *'
|
||||||
|
Array.prototype.for-each.call all, (el) ~>
|
||||||
|
el.add-event-listener \mousedown @mousedown
|
||||||
|
@root.style.display = \block
|
||||||
|
@root.style.left = pos.x + \px
|
||||||
|
@root.style.top = pos.y + \px
|
||||||
|
|
||||||
@mousedown = (e) ~>
|
Velocity @root, \finish true
|
||||||
e.prevent-default!
|
Velocity @root, { opacity: 0 } 0ms
|
||||||
if (!contains @root, e.target) and (@root != e.target)
|
Velocity @root, {
|
||||||
@close!
|
opacity: 1
|
||||||
return false
|
} {
|
||||||
|
queue: false
|
||||||
|
duration: 100ms
|
||||||
|
easing: \linear
|
||||||
|
}
|
||||||
|
|
||||||
@open = (pos) ~>
|
@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.add-event-listener \mousedown @mousedown
|
el.remove-event-listener \mousedown @mousedown
|
||||||
@root.style.display = \block
|
@trigger \closed
|
||||||
@root.style.left = pos.x + \px
|
@unmount!
|
||||||
@root.style.top = pos.y + \px
|
|
||||||
|
|
||||||
Velocity @root, \finish true
|
function contains(parent, child)
|
||||||
Velocity @root, { opacity: 0 } 0ms
|
node = child.parent-node
|
||||||
Velocity @root, {
|
while (node != null)
|
||||||
opacity: 1
|
if (node == parent)
|
||||||
} {
|
return true
|
||||||
queue: false
|
node = node.parent-node
|
||||||
duration: 100ms
|
return false
|
||||||
easing: \linear
|
</script>
|
||||||
}
|
</mk-contextmenu>
|
||||||
|
|
||||||
@close = ~>
|
|
||||||
all = document.query-selector-all 'body *'
|
|
||||||
Array.prototype.for-each.call all, (el) ~>
|
|
||||||
el.remove-event-listener \mousedown @mousedown
|
|
||||||
@trigger \closed
|
|
||||||
@unmount!
|
|
||||||
|
|
||||||
function contains(parent, child)
|
|
||||||
node = child.parent-node
|
|
||||||
while (node != null)
|
|
||||||
if (node == parent)
|
|
||||||
return true
|
|
||||||
node = node.parent-node
|
|
||||||
return false
|
|
||||||
|
|
|
@ -1,189 +1,188 @@
|
||||||
mk-crop-window
|
<mk-crop-window>
|
||||||
mk-window@window(is-modal={ true }, width={ '800px' })
|
<mk-window ref="window" is-modal="{ true }" width="{ '800px' }"><yield to="header"><i class="fa fa-crop"></i>{ parent.title }</yield>
|
||||||
<yield to="header">
|
<yield to="content">
|
||||||
i.fa.fa-crop
|
<div class="body"><img ref="img" src="{ parent.image.url + '?thumbnail&quality=80' }" alt=""/></div>
|
||||||
| { parent.title }
|
<div class="action">
|
||||||
</yield>
|
<button class="skip" onclick="{ parent.skip }">クロップをスキップ</button>
|
||||||
<yield to="content">
|
<button class="cancel" onclick="{ parent.cancel }">キャンセル</button>
|
||||||
div.body
|
<button class="ok" onclick="{ parent.ok }">決定</button>
|
||||||
img@img(src={ parent.image.url + '?thumbnail&quality=80' }, alt='')
|
</div></yield>
|
||||||
div.action
|
</mk-window>
|
||||||
button.skip(onclick={ parent.skip }) クロップをスキップ
|
<style type="stylus">
|
||||||
button.cancel(onclick={ parent.cancel }) キャンセル
|
:scope
|
||||||
button.ok(onclick={ parent.ok }) 決定
|
display block
|
||||||
</yield>
|
|
||||||
|
|
||||||
style.
|
> mk-window
|
||||||
display block
|
[data-yield='header']
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
> mk-window
|
[data-yield='content']
|
||||||
[data-yield='header']
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
[data-yield='content']
|
> .body
|
||||||
|
> img
|
||||||
|
width 100%
|
||||||
|
max-height 400px
|
||||||
|
|
||||||
> .body
|
.cropper-modal {
|
||||||
> img
|
opacity: 0.8;
|
||||||
width 100%
|
}
|
||||||
max-height 400px
|
|
||||||
|
|
||||||
.cropper-modal {
|
.cropper-view-box {
|
||||||
opacity: 0.8;
|
outline-color: $theme-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cropper-view-box {
|
.cropper-line, .cropper-point {
|
||||||
outline-color: $theme-color;
|
background-color: $theme-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cropper-line, .cropper-point {
|
.cropper-bg {
|
||||||
background-color: $theme-color;
|
animation: cropper-bg 0.5s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cropper-bg {
|
@-webkit-keyframes cropper-bg {
|
||||||
animation: cropper-bg 0.5s linear infinite;
|
0% {
|
||||||
}
|
background-position: 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
@-webkit-keyframes cropper-bg {
|
100% {
|
||||||
0% {
|
background-position: -8px -8px;
|
||||||
background-position: 0 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
@-moz-keyframes cropper-bg {
|
||||||
background-position: -8px -8px;
|
0% {
|
||||||
}
|
background-position: 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@-moz-keyframes cropper-bg {
|
100% {
|
||||||
0% {
|
background-position: -8px -8px;
|
||||||
background-position: 0 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
@-ms-keyframes cropper-bg {
|
||||||
background-position: -8px -8px;
|
0% {
|
||||||
}
|
background-position: 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@-ms-keyframes cropper-bg {
|
100% {
|
||||||
0% {
|
background-position: -8px -8px;
|
||||||
background-position: 0 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
@keyframes cropper-bg {
|
||||||
background-position: -8px -8px;
|
0% {
|
||||||
}
|
background-position: 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes cropper-bg {
|
100% {
|
||||||
0% {
|
background-position: -8px -8px;
|
||||||
background-position: 0 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
> .action
|
||||||
background-position: -8px -8px;
|
height 72px
|
||||||
}
|
background lighten($theme-color, 95%)
|
||||||
}
|
|
||||||
|
|
||||||
> .action
|
.ok
|
||||||
height 72px
|
.cancel
|
||||||
background lighten($theme-color, 95%)
|
.skip
|
||||||
|
display block
|
||||||
.ok
|
|
||||||
.cancel
|
|
||||||
.skip
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
bottom 16px
|
|
||||||
cursor pointer
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
height 40px
|
|
||||||
font-size 1em
|
|
||||||
outline none
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
position absolute
|
||||||
top -5px
|
bottom 16px
|
||||||
right -5px
|
cursor pointer
|
||||||
bottom -5px
|
padding 0
|
||||||
left -5px
|
margin 0
|
||||||
border 2px solid rgba($theme-color, 0.3)
|
height 40px
|
||||||
border-radius 8px
|
font-size 1em
|
||||||
|
outline none
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
&:disabled
|
&:focus
|
||||||
opacity 0.7
|
&:after
|
||||||
cursor default
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
position absolute
|
||||||
|
top -5px
|
||||||
|
right -5px
|
||||||
|
bottom -5px
|
||||||
|
left -5px
|
||||||
|
border 2px solid rgba($theme-color, 0.3)
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
.ok
|
&:disabled
|
||||||
.cancel
|
opacity 0.7
|
||||||
width 120px
|
cursor default
|
||||||
|
|
||||||
.ok
|
.ok
|
||||||
right 16px
|
.cancel
|
||||||
color $theme-color-foreground
|
width 120px
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
|
||||||
border solid 1px lighten($theme-color, 15%)
|
|
||||||
|
|
||||||
&:not(:disabled)
|
.ok
|
||||||
font-weight bold
|
right 16px
|
||||||
|
color $theme-color-foreground
|
||||||
|
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
||||||
|
border solid 1px lighten($theme-color, 15%)
|
||||||
|
|
||||||
&:hover:not(:disabled)
|
&:not(:disabled)
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
font-weight bold
|
||||||
border-color $theme-color
|
|
||||||
|
|
||||||
&:active:not(:disabled)
|
&:hover:not(:disabled)
|
||||||
background $theme-color
|
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
||||||
border-color $theme-color
|
border-color $theme-color
|
||||||
|
|
||||||
.cancel
|
&:active:not(:disabled)
|
||||||
.skip
|
background $theme-color
|
||||||
color #888
|
border-color $theme-color
|
||||||
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
|
||||||
border solid 1px #e2e2e2
|
|
||||||
|
|
||||||
&:hover
|
.cancel
|
||||||
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
.skip
|
||||||
border-color #dcdcdc
|
color #888
|
||||||
|
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
||||||
|
border solid 1px #e2e2e2
|
||||||
|
|
||||||
&:active
|
&:hover
|
||||||
background #ececec
|
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
||||||
border-color #dcdcdc
|
border-color #dcdcdc
|
||||||
|
|
||||||
.cancel
|
&:active
|
||||||
right 148px
|
background #ececec
|
||||||
|
border-color #dcdcdc
|
||||||
|
|
||||||
.skip
|
.cancel
|
||||||
left 16px
|
right 148px
|
||||||
width 150px
|
|
||||||
|
|
||||||
script.
|
.skip
|
||||||
@mixin \cropper
|
left 16px
|
||||||
|
width 150px
|
||||||
|
|
||||||
@image = @opts.file
|
</style>
|
||||||
@title = @opts.title
|
<script>
|
||||||
@aspect-ratio = @opts.aspect-ratio
|
@mixin \cropper
|
||||||
@cropper = null
|
|
||||||
|
|
||||||
@on \mount ~>
|
@image = @opts.file
|
||||||
@img = @refs.window.refs.img
|
@title = @opts.title
|
||||||
@cropper = new @Cropper @img, do
|
@aspect-ratio = @opts.aspect-ratio
|
||||||
aspect-ratio: @aspect-ratio
|
@cropper = null
|
||||||
highlight: no
|
|
||||||
view-mode: 1
|
|
||||||
|
|
||||||
@ok = ~>
|
@on \mount ~>
|
||||||
@cropper.get-cropped-canvas!.to-blob (blob) ~>
|
@img = @refs.window.refs.img
|
||||||
@trigger \cropped blob
|
@cropper = new @Cropper @img, do
|
||||||
|
aspect-ratio: @aspect-ratio
|
||||||
|
highlight: no
|
||||||
|
view-mode: 1
|
||||||
|
|
||||||
|
@ok = ~>
|
||||||
|
@cropper.get-cropped-canvas!.to-blob (blob) ~>
|
||||||
|
@trigger \cropped blob
|
||||||
|
@refs.window.close!
|
||||||
|
|
||||||
|
@skip = ~>
|
||||||
|
@trigger \skiped
|
||||||
@refs.window.close!
|
@refs.window.close!
|
||||||
|
|
||||||
@skip = ~>
|
@cancel = ~>
|
||||||
@trigger \skiped
|
@trigger \canceled
|
||||||
@refs.window.close!
|
@refs.window.close!
|
||||||
|
</script>
|
||||||
@cancel = ~>
|
</mk-crop-window>
|
||||||
@trigger \canceled
|
|
||||||
@refs.window.close!
|
|
||||||
|
|
|
@ -1,87 +1,90 @@
|
||||||
mk-debugger
|
<mk-debugger>
|
||||||
mk-window@window(is-modal={ false }, width={ '700px' }, height={ '550px' })
|
<mk-window ref="window" is-modal="{ false }" width="{ '700px' }" height="{ '550px' }"><yield to="header"><i class="fa fa-wrench"></i>Debugger</yield>
|
||||||
<yield to="header">
|
<yield to="content">
|
||||||
i.fa.fa-wrench
|
<section class="progress-dialog">
|
||||||
| Debugger
|
<h1>progress-dialog</h1>
|
||||||
</yield>
|
<button class="style-normal" onclick="{ parent.progressDialog }"><i class="fa fa-play"></i></button>
|
||||||
<yield to="content">
|
<button class="style-normal" onclick="{ parent.progressDialogDestroy }"><i class="fa fa-stop"></i></button>
|
||||||
section.progress-dialog
|
<label>
|
||||||
h1 progress-dialog
|
<p>TITLE:</p>
|
||||||
button.style-normal(onclick={ parent.progress-dialog }): i.fa.fa-play
|
<input ref="progressTitle" value="Title"/>
|
||||||
button.style-normal(onclick={ parent.progress-dialog-destroy }): i.fa.fa-stop
|
</label>
|
||||||
label
|
<label>
|
||||||
p TITLE:
|
<p>VAL:</p>
|
||||||
input@progress-title(value='Title')
|
<input ref="progressValue" type="number" oninput="{ parent.progressChange }" value="0"/>
|
||||||
label
|
</label>
|
||||||
p VAL:
|
<label>
|
||||||
input@progress-value(type='number', oninput={ parent.progress-change }, value=0)
|
<p>MAX:</p>
|
||||||
label
|
<input ref="progressMax" type="number" oninput="{ parent.progressChange }" value="100"/>
|
||||||
p MAX:
|
</label>
|
||||||
input@progress-max(type='number', oninput={ parent.progress-change }, value=100)
|
</section></yield>
|
||||||
</yield>
|
</mk-window>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
> mk-window
|
||||||
|
[data-yield='header']
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
style.
|
[data-yield='content']
|
||||||
> mk-window
|
overflow auto
|
||||||
[data-yield='header']
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
[data-yield='content']
|
> section
|
||||||
overflow auto
|
padding 32px
|
||||||
|
|
||||||
> section
|
// & + section
|
||||||
padding 32px
|
// margin-top 16px
|
||||||
|
|
||||||
// & + section
|
> h1
|
||||||
// margin-top 16px
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 0 0 8px 0
|
||||||
|
font-size 1em
|
||||||
|
color #555
|
||||||
|
border-bottom solid 1px #eee
|
||||||
|
|
||||||
> h1
|
> label
|
||||||
display block
|
display block
|
||||||
margin 0
|
|
||||||
padding 0 0 8px 0
|
|
||||||
font-size 1em
|
|
||||||
color #555
|
|
||||||
border-bottom solid 1px #eee
|
|
||||||
|
|
||||||
> label
|
> p
|
||||||
display block
|
display inline
|
||||||
|
margin 0
|
||||||
|
|
||||||
> p
|
> .progress-dialog
|
||||||
display inline
|
button
|
||||||
margin 0
|
display inline-block
|
||||||
|
margin 8px
|
||||||
|
|
||||||
> .progress-dialog
|
</style>
|
||||||
button
|
<script>
|
||||||
display inline-block
|
@mixin \open-window
|
||||||
margin 8px
|
|
||||||
|
|
||||||
script.
|
@on \mount ~>
|
||||||
@mixin \open-window
|
@progress-title = @tags['mk-window'].progress-title
|
||||||
|
@progress-value = @tags['mk-window'].progress-value
|
||||||
|
@progress-max = @tags['mk-window'].progress-max
|
||||||
|
|
||||||
@on \mount ~>
|
@refs.window.on \closed ~>
|
||||||
@progress-title = @tags['mk-window'].progress-title
|
@unmount!
|
||||||
@progress-value = @tags['mk-window'].progress-value
|
|
||||||
@progress-max = @tags['mk-window'].progress-max
|
|
||||||
|
|
||||||
@refs.window.on \closed ~>
|
################################
|
||||||
@unmount!
|
|
||||||
|
|
||||||
################################
|
@progress-controller = riot.observable!
|
||||||
|
|
||||||
@progress-controller = riot.observable!
|
@progress-dialog = ~>
|
||||||
|
@open-window \mk-progress-dialog do
|
||||||
|
title: @progress-title.value
|
||||||
|
value: @progress-value.value
|
||||||
|
max: @progress-max.value
|
||||||
|
controller: @progress-controller
|
||||||
|
|
||||||
@progress-dialog = ~>
|
@progress-change = ~>
|
||||||
@open-window \mk-progress-dialog do
|
@progress-controller.trigger do
|
||||||
title: @progress-title.value
|
\update
|
||||||
value: @progress-value.value
|
@progress-value.value
|
||||||
max: @progress-max.value
|
@progress-max.value
|
||||||
controller: @progress-controller
|
|
||||||
|
|
||||||
@progress-change = ~>
|
@progress-dialog-destroy = ~>
|
||||||
@progress-controller.trigger do
|
@progress-controller.trigger \close
|
||||||
\update
|
</script>
|
||||||
@progress-value.value
|
</mk-debugger>
|
||||||
@progress-max.value
|
|
||||||
|
|
||||||
@progress-dialog-destroy = ~>
|
|
||||||
@progress-controller.trigger \close
|
|
||||||
|
|
|
@ -1,56 +1,60 @@
|
||||||
mk-detect-slow-internet-connection-notice
|
<mk-detect-slow-internet-connection-notice><i><i class="fa fa-exclamation"></i></i>
|
||||||
i: i.fa.fa-exclamation
|
<div>
|
||||||
div: p インターネット回線が遅いようです。
|
<p>インターネット回線が遅いようです。</p>
|
||||||
|
</div>
|
||||||
style.
|
<style type="stylus">
|
||||||
display block
|
:scope
|
||||||
pointer-events none
|
|
||||||
position fixed
|
|
||||||
z-index 16384
|
|
||||||
top 64px
|
|
||||||
right 16px
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
width 298px
|
|
||||||
font-size 0.9em
|
|
||||||
background #fff
|
|
||||||
box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
|
|
||||||
opacity 0
|
|
||||||
|
|
||||||
> i
|
|
||||||
display block
|
|
||||||
width 48px
|
|
||||||
line-height 48px
|
|
||||||
margin-right 0.25em
|
|
||||||
text-align center
|
|
||||||
color $theme-color-foreground
|
|
||||||
font-size 1.5em
|
|
||||||
background $theme-color
|
|
||||||
|
|
||||||
> div
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
left 48px
|
|
||||||
margin 0
|
|
||||||
width 250px
|
|
||||||
height 48px
|
|
||||||
color #666
|
|
||||||
|
|
||||||
> p
|
|
||||||
display block
|
display block
|
||||||
|
pointer-events none
|
||||||
|
position fixed
|
||||||
|
z-index 16384
|
||||||
|
top 64px
|
||||||
|
right 16px
|
||||||
margin 0
|
margin 0
|
||||||
padding 8px
|
padding 0
|
||||||
|
width 298px
|
||||||
|
font-size 0.9em
|
||||||
|
background #fff
|
||||||
|
box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
|
||||||
|
opacity 0
|
||||||
|
|
||||||
script.
|
> i
|
||||||
@mixin \net
|
display block
|
||||||
|
width 48px
|
||||||
|
line-height 48px
|
||||||
|
margin-right 0.25em
|
||||||
|
text-align center
|
||||||
|
color $theme-color-foreground
|
||||||
|
font-size 1.5em
|
||||||
|
background $theme-color
|
||||||
|
|
||||||
@net.on \detected-slow-network ~>
|
> div
|
||||||
Velocity @root, {
|
display block
|
||||||
opacity: 1
|
position absolute
|
||||||
} 200ms \linear
|
top 0
|
||||||
set-timeout ~>
|
left 48px
|
||||||
|
margin 0
|
||||||
|
width 250px
|
||||||
|
height 48px
|
||||||
|
color #666
|
||||||
|
|
||||||
|
> p
|
||||||
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 8px
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \net
|
||||||
|
|
||||||
|
@net.on \detected-slow-network ~>
|
||||||
Velocity @root, {
|
Velocity @root, {
|
||||||
opacity: 0
|
opacity: 1
|
||||||
} 200ms \linear
|
} 200ms \linear
|
||||||
, 10000ms
|
set-timeout ~>
|
||||||
|
Velocity @root, {
|
||||||
|
opacity: 0
|
||||||
|
} 200ms \linear
|
||||||
|
, 10000ms
|
||||||
|
</script>
|
||||||
|
</mk-detect-slow-internet-connection-notice>
|
||||||
|
|
|
@ -1,141 +1,147 @@
|
||||||
mk-dialog
|
<mk-dialog>
|
||||||
div.bg@bg(onclick={ bg-click })
|
<div class="bg" ref="bg" onclick="{ bgClick }"></div>
|
||||||
div.main@main
|
<div class="main" ref="main">
|
||||||
header@header
|
<header ref="header"></header>
|
||||||
div.body@body
|
<div class="body" ref="body"></div>
|
||||||
div.buttons
|
<div class="buttons">
|
||||||
virtual(each={ opts.buttons })
|
<virtual each="{ opts.buttons }">
|
||||||
button(onclick={ _onclick }) { text }
|
<button onclick="{ _onclick }">{ text }</button>
|
||||||
|
</virtual>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
> .bg
|
||||||
display block
|
display block
|
||||||
|
position fixed
|
||||||
|
z-index 8192
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
background rgba(0, 0, 0, 0.7)
|
||||||
|
opacity 0
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
> .bg
|
> .main
|
||||||
display block
|
display block
|
||||||
position fixed
|
position fixed
|
||||||
z-index 8192
|
z-index 8192
|
||||||
top 0
|
top 20%
|
||||||
left 0
|
left 0
|
||||||
width 100%
|
right 0
|
||||||
height 100%
|
margin 0 auto 0 auto
|
||||||
background rgba(0, 0, 0, 0.7)
|
padding 32px 42px
|
||||||
opacity 0
|
width 480px
|
||||||
pointer-events none
|
background #fff
|
||||||
|
|
||||||
> .main
|
> header
|
||||||
display block
|
margin 1em 0
|
||||||
position fixed
|
|
||||||
z-index 8192
|
|
||||||
top 20%
|
|
||||||
left 0
|
|
||||||
right 0
|
|
||||||
margin 0 auto 0 auto
|
|
||||||
padding 32px 42px
|
|
||||||
width 480px
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
> header
|
|
||||||
margin 1em 0
|
|
||||||
color $theme-color
|
|
||||||
// color #43A4EC
|
|
||||||
font-weight bold
|
|
||||||
|
|
||||||
> i
|
|
||||||
margin-right 0.5em
|
|
||||||
|
|
||||||
> .body
|
|
||||||
margin 1em 0
|
|
||||||
color #888
|
|
||||||
|
|
||||||
> .buttons
|
|
||||||
> button
|
|
||||||
display inline-block
|
|
||||||
float right
|
|
||||||
margin 0
|
|
||||||
padding 10px 10px
|
|
||||||
font-size 1.1em
|
|
||||||
font-weight normal
|
|
||||||
text-decoration none
|
|
||||||
color #888
|
|
||||||
background transparent
|
|
||||||
outline none
|
|
||||||
border none
|
|
||||||
border-radius 0
|
|
||||||
cursor pointer
|
|
||||||
transition color 0.1s ease
|
|
||||||
|
|
||||||
i
|
|
||||||
margin 0 0.375em
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color $theme-color
|
color $theme-color
|
||||||
|
// color #43A4EC
|
||||||
|
font-weight bold
|
||||||
|
|
||||||
&:active
|
> i
|
||||||
color darken($theme-color, 10%)
|
margin-right 0.5em
|
||||||
transition color 0s ease
|
|
||||||
|
|
||||||
script.
|
> .body
|
||||||
@can-through = if opts.can-through? then opts.can-through else true
|
margin 1em 0
|
||||||
@opts.buttons.for-each (button) ~>
|
color #888
|
||||||
button._onclick = ~>
|
|
||||||
if button.onclick?
|
|
||||||
button.onclick!
|
|
||||||
@close!
|
|
||||||
|
|
||||||
@on \mount ~>
|
> .buttons
|
||||||
@refs.header.innerHTML = @opts.title
|
> button
|
||||||
@refs.body.innerHTML = @opts.text
|
display inline-block
|
||||||
|
float right
|
||||||
|
margin 0
|
||||||
|
padding 10px 10px
|
||||||
|
font-size 1.1em
|
||||||
|
font-weight normal
|
||||||
|
text-decoration none
|
||||||
|
color #888
|
||||||
|
background transparent
|
||||||
|
outline none
|
||||||
|
border none
|
||||||
|
border-radius 0
|
||||||
|
cursor pointer
|
||||||
|
transition color 0.1s ease
|
||||||
|
|
||||||
@refs.bg.style.pointer-events = \auto
|
i
|
||||||
Velocity @refs.bg, \finish true
|
margin 0 0.375em
|
||||||
Velocity @refs.bg, {
|
|
||||||
opacity: 1
|
|
||||||
} {
|
|
||||||
queue: false
|
|
||||||
duration: 100ms
|
|
||||||
easing: \linear
|
|
||||||
}
|
|
||||||
|
|
||||||
Velocity @refs.main, {
|
&:hover
|
||||||
opacity: 0
|
color $theme-color
|
||||||
scale: 1.2
|
|
||||||
} {
|
|
||||||
duration: 0
|
|
||||||
}
|
|
||||||
Velocity @refs.main, {
|
|
||||||
opacity: 1
|
|
||||||
scale: 1
|
|
||||||
} {
|
|
||||||
duration: 300ms
|
|
||||||
easing: [ 0, 0.5, 0.5, 1 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@close = ~>
|
&:active
|
||||||
@refs.bg.style.pointer-events = \none
|
color darken($theme-color, 10%)
|
||||||
Velocity @refs.bg, \finish true
|
transition color 0s ease
|
||||||
Velocity @refs.bg, {
|
|
||||||
opacity: 0
|
|
||||||
} {
|
|
||||||
queue: false
|
|
||||||
duration: 300ms
|
|
||||||
easing: \linear
|
|
||||||
}
|
|
||||||
|
|
||||||
@refs.main.style.pointer-events = \none
|
</style>
|
||||||
Velocity @refs.main, \finish true
|
<script>
|
||||||
Velocity @refs.main, {
|
@can-through = if opts.can-through? then opts.can-through else true
|
||||||
opacity: 0
|
@opts.buttons.for-each (button) ~>
|
||||||
scale: 0.8
|
button._onclick = ~>
|
||||||
} {
|
if button.onclick?
|
||||||
queue: false
|
button.onclick!
|
||||||
duration: 300ms
|
@close!
|
||||||
easing: [ 0.5, -0.5, 1, 0.5 ]
|
|
||||||
complete: ~>
|
|
||||||
@unmount!
|
|
||||||
}
|
|
||||||
|
|
||||||
@bg-click = ~>
|
@on \mount ~>
|
||||||
if @can-through
|
@refs.header.innerHTML = @opts.title
|
||||||
if @opts.on-through?
|
@refs.body.innerHTML = @opts.text
|
||||||
@opts.on-through!
|
|
||||||
@close!
|
@refs.bg.style.pointer-events = \auto
|
||||||
|
Velocity @refs.bg, \finish true
|
||||||
|
Velocity @refs.bg, {
|
||||||
|
opacity: 1
|
||||||
|
} {
|
||||||
|
queue: false
|
||||||
|
duration: 100ms
|
||||||
|
easing: \linear
|
||||||
|
}
|
||||||
|
|
||||||
|
Velocity @refs.main, {
|
||||||
|
opacity: 0
|
||||||
|
scale: 1.2
|
||||||
|
} {
|
||||||
|
duration: 0
|
||||||
|
}
|
||||||
|
Velocity @refs.main, {
|
||||||
|
opacity: 1
|
||||||
|
scale: 1
|
||||||
|
} {
|
||||||
|
duration: 300ms
|
||||||
|
easing: [ 0, 0.5, 0.5, 1 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@close = ~>
|
||||||
|
@refs.bg.style.pointer-events = \none
|
||||||
|
Velocity @refs.bg, \finish true
|
||||||
|
Velocity @refs.bg, {
|
||||||
|
opacity: 0
|
||||||
|
} {
|
||||||
|
queue: false
|
||||||
|
duration: 300ms
|
||||||
|
easing: \linear
|
||||||
|
}
|
||||||
|
|
||||||
|
@refs.main.style.pointer-events = \none
|
||||||
|
Velocity @refs.main, \finish true
|
||||||
|
Velocity @refs.main, {
|
||||||
|
opacity: 0
|
||||||
|
scale: 0.8
|
||||||
|
} {
|
||||||
|
queue: false
|
||||||
|
duration: 300ms
|
||||||
|
easing: [ 0.5, -0.5, 1, 0.5 ]
|
||||||
|
complete: ~>
|
||||||
|
@unmount!
|
||||||
|
}
|
||||||
|
|
||||||
|
@bg-click = ~>
|
||||||
|
if @can-through
|
||||||
|
if @opts.on-through?
|
||||||
|
@opts.on-through!
|
||||||
|
@close!
|
||||||
|
</script>
|
||||||
|
</mk-dialog>
|
||||||
|
|
|
@ -1,63 +1,68 @@
|
||||||
mk-donation
|
<mk-donation>
|
||||||
button.close(onclick={ close }) 閉じる x
|
<button class="close" onclick="{ close }">閉じる x</button>
|
||||||
div.message
|
<div class="message">
|
||||||
p 利用者の皆さま、
|
<p>利用者の皆さま、</p>
|
||||||
p
|
<p>
|
||||||
| 今日は、日本の皆さまにお知らせがあります。
|
今日は、日本の皆さまにお知らせがあります。
|
||||||
| Misskeyの援助をお願いいたします。
|
Misskeyの援助をお願いいたします。
|
||||||
| 私は独立性を守るため、一切の広告を掲載いたしません。
|
私は独立性を守るため、一切の広告を掲載いたしません。
|
||||||
| 平均で約¥1,500の寄付をいただき、運営しております。
|
平均で約¥1,500の寄付をいただき、運営しております。
|
||||||
| 援助をしてくださる利用者はほんの少数です。
|
援助をしてくださる利用者はほんの少数です。
|
||||||
| お願いいたします。
|
お願いいたします。
|
||||||
| 今日、利用者の皆さまが¥300ご援助くだされば、募金活動を一時間で終了することができます。
|
今日、利用者の皆さまが¥300ご援助くだされば、募金活動を一時間で終了することができます。
|
||||||
| コーヒー1杯ほどの金額です。
|
コーヒー1杯ほどの金額です。
|
||||||
| Misskeyを活用しておられるのでしたら、広告を掲載せずにもう1年活動できるよう、どうか1分だけお時間をください。
|
Misskeyを活用しておられるのでしたら、広告を掲載せずにもう1年活動できるよう、どうか1分だけお時間をください。
|
||||||
| 私は小さな非営利個人ですが、サーバー、プログラム、人件費など、世界でトップクラスのウェブサイト同等のコストがかかります。
|
私は小さな非営利個人ですが、サーバー、プログラム、人件費など、世界でトップクラスのウェブサイト同等のコストがかかります。
|
||||||
| 利用者は何億人といますが、他の大きなサイトに比べてほんの少額の費用で運営しているのです。
|
利用者は何億人といますが、他の大きなサイトに比べてほんの少額の費用で運営しているのです。
|
||||||
| 人間の可能性、自由、そして機会。知識こそ、これらの基盤を成すものです。
|
人間の可能性、自由、そして機会。知識こそ、これらの基盤を成すものです。
|
||||||
| 私は、誰もが無料かつ制限なく知識に触れられるべきだと信じています。
|
私は、誰もが無料かつ制限なく知識に触れられるべきだと信じています。
|
||||||
| 募金活動を終了し、Misskeyの改善に戻れるようご援助ください。
|
募金活動を終了し、Misskeyの改善に戻れるようご援助ください。
|
||||||
| よろしくお願いいたします。
|
よろしくお願いいたします。
|
||||||
|
</p>
|
||||||
style.
|
</div>
|
||||||
display block
|
<style type="stylus">
|
||||||
color #fff
|
:scope
|
||||||
background #03072C
|
|
||||||
|
|
||||||
> .close
|
|
||||||
position absolute
|
|
||||||
top 16px
|
|
||||||
right 16px
|
|
||||||
z-index 1
|
|
||||||
|
|
||||||
> .message
|
|
||||||
padding 32px
|
|
||||||
font-size 1.4em
|
|
||||||
font-family serif
|
|
||||||
|
|
||||||
> p
|
|
||||||
display block
|
display block
|
||||||
margin 0 auto
|
color #fff
|
||||||
max-width 1200px
|
background #03072C
|
||||||
|
|
||||||
> p:first-child
|
> .close
|
||||||
margin-bottom 16px
|
position absolute
|
||||||
|
top 16px
|
||||||
|
right 16px
|
||||||
|
z-index 1
|
||||||
|
|
||||||
script.
|
> .message
|
||||||
@mixin \api
|
padding 32px
|
||||||
@mixin \i
|
font-size 1.4em
|
||||||
|
font-family serif
|
||||||
|
|
||||||
@close = (e) ~>
|
> p
|
||||||
e.prevent-default!
|
display block
|
||||||
e.stop-propagation!
|
margin 0 auto
|
||||||
|
max-width 1200px
|
||||||
|
|
||||||
@I.data.no_donation = true
|
> p:first-child
|
||||||
@api \i/appdata/set do
|
margin-bottom 16px
|
||||||
data: JSON.stringify do
|
|
||||||
no_donation: @I.data.no_donation
|
|
||||||
.then ~>
|
|
||||||
@update-i!
|
|
||||||
|
|
||||||
@unmount!
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \i
|
||||||
|
|
||||||
@parent.parent.set-root-layout!
|
@close = (e) ~>
|
||||||
|
e.prevent-default!
|
||||||
|
e.stop-propagation!
|
||||||
|
|
||||||
|
@I.data.no_donation = true
|
||||||
|
@api \i/appdata/set do
|
||||||
|
data: JSON.stringify do
|
||||||
|
no_donation: @I.data.no_donation
|
||||||
|
.then ~>
|
||||||
|
@update-i!
|
||||||
|
|
||||||
|
@unmount!
|
||||||
|
|
||||||
|
@parent.parent.set-root-layout!
|
||||||
|
</script>
|
||||||
|
</mk-donation>
|
||||||
|
|
|
@ -1,28 +1,31 @@
|
||||||
mk-drive-browser-base-contextmenu
|
<mk-drive-browser-base-contextmenu>
|
||||||
mk-contextmenu@ctx
|
<mk-contextmenu ref="ctx">
|
||||||
ul
|
<ul>
|
||||||
li(onclick={ parent.create-folder }): p
|
<li onclick="{ parent.createFolder }">
|
||||||
i.fa.fa-folder-o
|
<p><i class="fa fa-folder-o"></i>フォルダーを作成</p>
|
||||||
| フォルダーを作成
|
</li>
|
||||||
li(onclick={ parent.upload }): p
|
<li onclick="{ parent.upload }">
|
||||||
i.fa.fa-upload
|
<p><i class="fa fa-upload"></i>ファイルをアップロード</p>
|
||||||
| ファイルをアップロード
|
</li>
|
||||||
|
</ul>
|
||||||
|
</mk-contextmenu>
|
||||||
|
<script>
|
||||||
|
@browser = @opts.browser
|
||||||
|
|
||||||
script.
|
@on \mount ~>
|
||||||
@browser = @opts.browser
|
@refs.ctx.on \closed ~>
|
||||||
|
@trigger \closed
|
||||||
|
@unmount!
|
||||||
|
|
||||||
@on \mount ~>
|
@open = (pos) ~>
|
||||||
@refs.ctx.on \closed ~>
|
@refs.ctx.open pos
|
||||||
@trigger \closed
|
|
||||||
@unmount!
|
|
||||||
|
|
||||||
@open = (pos) ~>
|
@create-folder = ~>
|
||||||
@refs.ctx.open pos
|
@browser.create-folder!
|
||||||
|
@refs.ctx.close!
|
||||||
|
|
||||||
@create-folder = ~>
|
@upload = ~>
|
||||||
@browser.create-folder!
|
@browser.select-local-file!
|
||||||
@refs.ctx.close!
|
@refs.ctx.close!
|
||||||
|
</script>
|
||||||
@upload = ~>
|
</mk-drive-browser-base-contextmenu>
|
||||||
@browser.select-local-file!
|
|
||||||
@refs.ctx.close!
|
|
||||||
|
|
|
@ -1,29 +1,28 @@
|
||||||
mk-drive-browser-window
|
<mk-drive-browser-window>
|
||||||
mk-window@window(is-modal={ false }, width={ '800px' }, height={ '500px' })
|
<mk-window ref="window" is-modal="{ false }" width="{ '800px' }" height="{ '500px' }"><yield to="header"><i class="fa fa-cloud"></i>ドライブ</yield>
|
||||||
<yield to="header">
|
<yield to="content">
|
||||||
i.fa.fa-cloud
|
<mk-drive-browser multiple="{ true }" folder="{ parent.folder }"></mk-drive-browser></yield>
|
||||||
| ドライブ
|
</mk-window>
|
||||||
</yield>
|
<style type="stylus">
|
||||||
<yield to="content">
|
:scope
|
||||||
mk-drive-browser(multiple={ true }, folder={ parent.folder })
|
> mk-window
|
||||||
</yield>
|
[data-yield='header']
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
style.
|
[data-yield='content']
|
||||||
> mk-window
|
> mk-drive-browser
|
||||||
[data-yield='header']
|
height 100%
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
[data-yield='content']
|
</style>
|
||||||
> mk-drive-browser
|
<script>
|
||||||
height 100%
|
@folder = if @opts.folder? then @opts.folder else null
|
||||||
|
|
||||||
script.
|
@on \mount ~>
|
||||||
@folder = if @opts.folder? then @opts.folder else null
|
@refs.window.on \closed ~>
|
||||||
|
@unmount!
|
||||||
|
|
||||||
@on \mount ~>
|
@close = ~>
|
||||||
@refs.window.on \closed ~>
|
@refs.window.close!
|
||||||
@unmount!
|
</script>
|
||||||
|
</mk-drive-browser-window>
|
||||||
@close = ~>
|
|
||||||
@refs.window.close!
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,97 +1,103 @@
|
||||||
mk-drive-browser-file-contextmenu
|
<mk-drive-browser-file-contextmenu>
|
||||||
mk-contextmenu@ctx: ul
|
<mk-contextmenu ref="ctx">
|
||||||
li(onclick={ parent.rename }): p
|
<ul>
|
||||||
i.fa.fa-i-cursor
|
<li onclick="{ parent.rename }">
|
||||||
| 名前を変更
|
<p><i class="fa fa-i-cursor"></i>名前を変更</p>
|
||||||
li(onclick={ parent.copy-url }): p
|
</li>
|
||||||
i.fa.fa-link
|
<li onclick="{ parent.copyUrl }">
|
||||||
| URLをコピー
|
<p><i class="fa fa-link"></i>URLをコピー</p>
|
||||||
li: a(href={ parent.file.url + '?download' }, download={ parent.file.name }, onclick={ parent.download })
|
</li>
|
||||||
i.fa.fa-download
|
<li><a href="{ parent.file.url + '?download' }" download="{ parent.file.name }" onclick="{ parent.download }"><i class="fa fa-download"></i>ダウンロード</a></li>
|
||||||
| ダウンロード
|
<li class="separator"></li>
|
||||||
li.separator
|
<li onclick="{ parent.delete }">
|
||||||
li(onclick={ parent.delete }): p
|
<p><i class="fa fa-trash-o"></i>削除</p>
|
||||||
i.fa.fa-trash-o
|
</li>
|
||||||
| 削除
|
<li class="separator"></li>
|
||||||
li.separator
|
<li class="has-child">
|
||||||
li.has-child
|
<p>その他...<i class="fa fa-caret-right"></i></p>
|
||||||
p
|
<ul>
|
||||||
| その他...
|
<li onclick="{ parent.setAvatar }">
|
||||||
i.fa.fa-caret-right
|
<p>アバターに設定</p>
|
||||||
ul
|
</li>
|
||||||
li(onclick={ parent.set-avatar }): p
|
<li onclick="{ parent.setBanner }">
|
||||||
| アバターに設定
|
<p>バナーに設定</p>
|
||||||
li(onclick={ parent.set-banner }): p
|
</li>
|
||||||
| バナーに設定
|
<li onclick="{ parent.setWallpaper }">
|
||||||
li(onclick={ parent.set-wallpaper }): p
|
<p>壁紙に設定</p>
|
||||||
| 壁紙に設定
|
</li>
|
||||||
li.has-child
|
</ul>
|
||||||
p
|
</li>
|
||||||
| アプリで開く...
|
<li class="has-child">
|
||||||
i.fa.fa-caret-right
|
<p>アプリで開く...<i class="fa fa-caret-right"></i></p>
|
||||||
ul
|
<ul>
|
||||||
li(onclick={ parent.add-app }): p
|
<li onclick="{ parent.addApp }">
|
||||||
| アプリを追加...
|
<p>アプリを追加...</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</mk-contextmenu>
|
||||||
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \i
|
||||||
|
@mixin \update-avatar
|
||||||
|
@mixin \update-banner
|
||||||
|
@mixin \update-wallpaper
|
||||||
|
@mixin \input-dialog
|
||||||
|
@mixin \NotImplementedException
|
||||||
|
|
||||||
script.
|
@browser = @opts.browser
|
||||||
@mixin \api
|
@file = @opts.file
|
||||||
@mixin \i
|
|
||||||
@mixin \update-avatar
|
|
||||||
@mixin \update-banner
|
|
||||||
@mixin \update-wallpaper
|
|
||||||
@mixin \input-dialog
|
|
||||||
@mixin \NotImplementedException
|
|
||||||
|
|
||||||
@browser = @opts.browser
|
@on \mount ~>
|
||||||
@file = @opts.file
|
@refs.ctx.on \closed ~>
|
||||||
|
@trigger \closed
|
||||||
|
@unmount!
|
||||||
|
|
||||||
@on \mount ~>
|
@open = (pos) ~>
|
||||||
@refs.ctx.on \closed ~>
|
@refs.ctx.open pos
|
||||||
@trigger \closed
|
|
||||||
@unmount!
|
|
||||||
|
|
||||||
@open = (pos) ~>
|
@rename = ~>
|
||||||
@refs.ctx.open pos
|
@refs.ctx.close!
|
||||||
|
|
||||||
@rename = ~>
|
name <~ @input-dialog do
|
||||||
@refs.ctx.close!
|
'ファイル名の変更'
|
||||||
|
'新しいファイル名を入力してください'
|
||||||
|
@file.name
|
||||||
|
|
||||||
name <~ @input-dialog do
|
@api \drive/files/update do
|
||||||
'ファイル名の変更'
|
file_id: @file.id
|
||||||
'新しいファイル名を入力してください'
|
name: name
|
||||||
@file.name
|
.then ~>
|
||||||
|
# something
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
@api \drive/files/update do
|
@copy-url = ~>
|
||||||
file_id: @file.id
|
@NotImplementedException!
|
||||||
name: name
|
|
||||||
.then ~>
|
|
||||||
# something
|
|
||||||
.catch (err) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@copy-url = ~>
|
@download = ~>
|
||||||
@NotImplementedException!
|
@refs.ctx.close!
|
||||||
|
|
||||||
@download = ~>
|
@set-avatar = ~>
|
||||||
@refs.ctx.close!
|
@refs.ctx.close!
|
||||||
|
@update-avatar @I, (i) ~>
|
||||||
|
@update-i i
|
||||||
|
, @file
|
||||||
|
|
||||||
@set-avatar = ~>
|
@set-banner = ~>
|
||||||
@refs.ctx.close!
|
@refs.ctx.close!
|
||||||
@update-avatar @I, (i) ~>
|
@update-banner @I, (i) ~>
|
||||||
@update-i i
|
@update-i i
|
||||||
, @file
|
, @file
|
||||||
|
|
||||||
@set-banner = ~>
|
@set-wallpaper = ~>
|
||||||
@refs.ctx.close!
|
@refs.ctx.close!
|
||||||
@update-banner @I, (i) ~>
|
@update-wallpaper @I, (i) ~>
|
||||||
@update-i i
|
@update-i i
|
||||||
, @file
|
, @file
|
||||||
|
|
||||||
@set-wallpaper = ~>
|
@add-app = ~>
|
||||||
@refs.ctx.close!
|
@NotImplementedException!
|
||||||
@update-wallpaper @I, (i) ~>
|
</script>
|
||||||
@update-i i
|
</mk-drive-browser-file-contextmenu>
|
||||||
, @file
|
|
||||||
|
|
||||||
@add-app = ~>
|
|
||||||
@NotImplementedException!
|
|
||||||
|
|
|
@ -1,207 +1,208 @@
|
||||||
mk-drive-browser-file(data-is-selected={ (file._selected || false).toString() }, data-is-contextmenu-showing={ is-contextmenu-showing.toString() }, onclick={ onclick }, oncontextmenu={ oncontextmenu }, draggable='true', ondragstart={ ondragstart }, ondragend={ ondragend }, title={ title })
|
<mk-drive-browser-file data-is-selected="{ (file._selected || false).toString() }" data-is-contextmenu-showing="{ isContextmenuShowing.toString() }" onclick="{ onclick }" oncontextmenu="{ oncontextmenu }" draggable="true" ondragstart="{ ondragstart }" ondragend="{ ondragend }" title="{ title }">
|
||||||
div.label(if={ I.avatar_id == file.id })
|
<div class="label" if="{ I.avatar_id == file.id }"><img src="/_/resources/label.svg"/>
|
||||||
img(src='/_/resources/label.svg')
|
<p>アバター</p>
|
||||||
p アバター
|
</div>
|
||||||
div.label(if={ I.banner_id == file.id })
|
<div class="label" if="{ I.banner_id == file.id }"><img src="/_/resources/label.svg"/>
|
||||||
img(src='/_/resources/label.svg')
|
<p>バナー</p>
|
||||||
p バナー
|
</div>
|
||||||
div.label(if={ I.data.wallpaper == file.id })
|
<div class="label" if="{ I.data.wallpaper == file.id }"><img src="/_/resources/label.svg"/>
|
||||||
img(src='/_/resources/label.svg')
|
<p>壁紙</p>
|
||||||
p 壁紙
|
</div>
|
||||||
div.thumbnail: img(src={ file.url + '?thumbnail&size=128' }, alt='')
|
<div class="thumbnail"><img src="{ file.url + '?thumbnail&size=128' }" alt=""/></div>
|
||||||
p.name
|
<p class="name"><span>{ file.name.lastIndexOf('.') != -1 ? file.name.substr(0, file.name.lastIndexOf('.')) : file.name }</span><span class="ext" if="{ file.name.lastIndexOf('.') != -1 }">{ file.name.substr(file.name.lastIndexOf('.')) }</span></p>
|
||||||
span { file.name.lastIndexOf('.') != -1 ? file.name.substr(0, file.name.lastIndexOf('.')) : file.name }
|
<style type="stylus">
|
||||||
span.ext(if={ file.name.lastIndexOf('.') != -1 }) { file.name.substr(file.name.lastIndexOf('.')) }
|
:scope
|
||||||
|
display block
|
||||||
style.
|
margin 4px
|
||||||
display block
|
padding 8px 0 0 0
|
||||||
margin 4px
|
width 144px
|
||||||
padding 8px 0 0 0
|
height 180px
|
||||||
width 144px
|
|
||||||
height 180px
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&, *
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background rgba(0, 0, 0, 0.05)
|
|
||||||
|
|
||||||
> .label
|
|
||||||
&:before
|
|
||||||
&:after
|
|
||||||
background #0b65a5
|
|
||||||
|
|
||||||
&:active
|
|
||||||
background rgba(0, 0, 0, 0.1)
|
|
||||||
|
|
||||||
> .label
|
|
||||||
&:before
|
|
||||||
&:after
|
|
||||||
background #0b588c
|
|
||||||
|
|
||||||
&[data-is-selected='true']
|
|
||||||
background $theme-color
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background lighten($theme-color, 10%)
|
|
||||||
|
|
||||||
&:active
|
|
||||||
background darken($theme-color, 10%)
|
|
||||||
|
|
||||||
> .label
|
|
||||||
&:before
|
|
||||||
&:after
|
|
||||||
display none
|
|
||||||
|
|
||||||
> .name
|
|
||||||
color $theme-color-foreground
|
|
||||||
|
|
||||||
&[data-is-contextmenu-showing='true']
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
|
||||||
top -4px
|
|
||||||
right -4px
|
|
||||||
bottom -4px
|
|
||||||
left -4px
|
|
||||||
border 2px dashed rgba($theme-color, 0.3)
|
|
||||||
border-radius 4px
|
border-radius 4px
|
||||||
|
|
||||||
> .label
|
&, *
|
||||||
position absolute
|
cursor pointer
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
pointer-events none
|
|
||||||
|
|
||||||
&:before
|
&:hover
|
||||||
content ""
|
background rgba(0, 0, 0, 0.05)
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
z-index 1
|
|
||||||
top 0
|
|
||||||
left 57px
|
|
||||||
width 28px
|
|
||||||
height 8px
|
|
||||||
background #0c7ac9
|
|
||||||
|
|
||||||
&:after
|
> .label
|
||||||
content ""
|
&:before
|
||||||
display block
|
&:after
|
||||||
position absolute
|
background #0b65a5
|
||||||
z-index 1
|
|
||||||
top 57px
|
|
||||||
left 0
|
|
||||||
width 8px
|
|
||||||
height 28px
|
|
||||||
background #0c7ac9
|
|
||||||
|
|
||||||
> img
|
&:active
|
||||||
position absolute
|
background rgba(0, 0, 0, 0.1)
|
||||||
z-index 2
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
|
|
||||||
> p
|
> .label
|
||||||
position absolute
|
&:before
|
||||||
z-index 3
|
&:after
|
||||||
top 19px
|
background #0b588c
|
||||||
left -28px
|
|
||||||
width 120px
|
|
||||||
margin 0
|
|
||||||
text-align center
|
|
||||||
line-height 28px
|
|
||||||
color #fff
|
|
||||||
transform rotate(-45deg)
|
|
||||||
|
|
||||||
> .thumbnail
|
&[data-is-selected='true']
|
||||||
width 128px
|
background $theme-color
|
||||||
height 128px
|
|
||||||
left 8px
|
|
||||||
|
|
||||||
> img
|
&:hover
|
||||||
display block
|
background lighten($theme-color, 10%)
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
right 0
|
|
||||||
bottom 0
|
|
||||||
margin auto
|
|
||||||
max-width 128px
|
|
||||||
max-height 128px
|
|
||||||
pointer-events none
|
|
||||||
|
|
||||||
> .name
|
&:active
|
||||||
display block
|
background darken($theme-color, 10%)
|
||||||
margin 4px 0 0 0
|
|
||||||
font-size 0.8em
|
|
||||||
text-align center
|
|
||||||
word-break break-all
|
|
||||||
color #444
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
> .ext
|
> .label
|
||||||
opacity 0.5
|
&:before
|
||||||
|
&:after
|
||||||
|
display none
|
||||||
|
|
||||||
script.
|
> .name
|
||||||
@mixin \i
|
color $theme-color-foreground
|
||||||
@mixin \bytes-to-size
|
|
||||||
|
|
||||||
@file = @opts.file
|
&[data-is-contextmenu-showing='true']
|
||||||
@browser = @parent
|
&:after
|
||||||
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
position absolute
|
||||||
|
top -4px
|
||||||
|
right -4px
|
||||||
|
bottom -4px
|
||||||
|
left -4px
|
||||||
|
border 2px dashed rgba($theme-color, 0.3)
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
@title = @file.name + '\n' + @file.type + ' ' + (@bytes-to-size @file.datasize)
|
> .label
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
@is-contextmenu-showing = false
|
&:before
|
||||||
|
content ""
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
z-index 1
|
||||||
|
top 0
|
||||||
|
left 57px
|
||||||
|
width 28px
|
||||||
|
height 8px
|
||||||
|
background #0c7ac9
|
||||||
|
|
||||||
@onclick = ~>
|
&:after
|
||||||
if @browser.multiple
|
content ""
|
||||||
if @file._selected?
|
display block
|
||||||
@file._selected = !@file._selected
|
position absolute
|
||||||
|
z-index 1
|
||||||
|
top 57px
|
||||||
|
left 0
|
||||||
|
width 8px
|
||||||
|
height 28px
|
||||||
|
background #0c7ac9
|
||||||
|
|
||||||
|
> img
|
||||||
|
position absolute
|
||||||
|
z-index 2
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
|
||||||
|
> p
|
||||||
|
position absolute
|
||||||
|
z-index 3
|
||||||
|
top 19px
|
||||||
|
left -28px
|
||||||
|
width 120px
|
||||||
|
margin 0
|
||||||
|
text-align center
|
||||||
|
line-height 28px
|
||||||
|
color #fff
|
||||||
|
transform rotate(-45deg)
|
||||||
|
|
||||||
|
> .thumbnail
|
||||||
|
width 128px
|
||||||
|
height 128px
|
||||||
|
left 8px
|
||||||
|
|
||||||
|
> img
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
bottom 0
|
||||||
|
margin auto
|
||||||
|
max-width 128px
|
||||||
|
max-height 128px
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
|
> .name
|
||||||
|
display block
|
||||||
|
margin 4px 0 0 0
|
||||||
|
font-size 0.8em
|
||||||
|
text-align center
|
||||||
|
word-break break-all
|
||||||
|
color #444
|
||||||
|
overflow hidden
|
||||||
|
|
||||||
|
> .ext
|
||||||
|
opacity 0.5
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mixin \bytes-to-size
|
||||||
|
|
||||||
|
@file = @opts.file
|
||||||
|
@browser = @parent
|
||||||
|
|
||||||
|
@title = @file.name + '\n' + @file.type + ' ' + (@bytes-to-size @file.datasize)
|
||||||
|
|
||||||
|
@is-contextmenu-showing = false
|
||||||
|
|
||||||
|
@onclick = ~>
|
||||||
|
if @browser.multiple
|
||||||
|
if @file._selected?
|
||||||
|
@file._selected = !@file._selected
|
||||||
|
else
|
||||||
|
@file._selected = true
|
||||||
|
@browser.trigger \change-selection @browser.get-selection!
|
||||||
else
|
else
|
||||||
@file._selected = true
|
if @file._selected
|
||||||
@browser.trigger \change-selection @browser.get-selection!
|
@browser.trigger \selected @file
|
||||||
else
|
else
|
||||||
if @file._selected
|
@browser.files.for-each (file) ~>
|
||||||
@browser.trigger \selected @file
|
file._selected = false
|
||||||
else
|
@file._selected = true
|
||||||
@browser.files.for-each (file) ~>
|
@browser.trigger \change-selection @file
|
||||||
file._selected = false
|
|
||||||
@file._selected = true
|
|
||||||
@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
|
@is-contextmenu-showing = true
|
||||||
@update!
|
|
||||||
ctx = document.body.append-child document.create-element \mk-drive-browser-file-contextmenu
|
|
||||||
ctx = riot.mount ctx, do
|
|
||||||
browser: @browser
|
|
||||||
file: @file
|
|
||||||
ctx = ctx.0
|
|
||||||
ctx.open do
|
|
||||||
x: e.page-x - window.page-x-offset
|
|
||||||
y: e.page-y - window.page-y-offset
|
|
||||||
ctx.on \closed ~>
|
|
||||||
@is-contextmenu-showing = false
|
|
||||||
@update!
|
@update!
|
||||||
return false
|
ctx = document.body.append-child document.create-element \mk-drive-browser-file-contextmenu
|
||||||
|
ctx = riot.mount ctx, do
|
||||||
|
browser: @browser
|
||||||
|
file: @file
|
||||||
|
ctx = ctx.0
|
||||||
|
ctx.open do
|
||||||
|
x: e.page-x - window.page-x-offset
|
||||||
|
y: e.page-y - window.page-y-offset
|
||||||
|
ctx.on \closed ~>
|
||||||
|
@is-contextmenu-showing = false
|
||||||
|
@update!
|
||||||
|
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
|
@is-dragging = true
|
||||||
|
|
||||||
# 親ブラウザに対して、ドラッグが開始されたフラグを立てる
|
# 親ブラウザに対して、ドラッグが開始されたフラグを立てる
|
||||||
# (=あなたの子供が、ドラッグを開始しましたよ)
|
# (=あなたの子供が、ドラッグを開始しましたよ)
|
||||||
@browser.is-drag-source = true
|
@browser.is-drag-source = true
|
||||||
|
|
||||||
@ondragend = (e) ~>
|
@ondragend = (e) ~>
|
||||||
@is-dragging = false
|
@is-dragging = false
|
||||||
@browser.is-drag-source = false
|
@browser.is-drag-source = false
|
||||||
|
</script>
|
||||||
|
</mk-drive-browser-file>
|
||||||
|
|
|
@ -1,62 +1,66 @@
|
||||||
mk-drive-browser-folder-contextmenu
|
<mk-drive-browser-folder-contextmenu>
|
||||||
mk-contextmenu@ctx: ul
|
<mk-contextmenu ref="ctx">
|
||||||
li(onclick={ parent.move }): p
|
<ul>
|
||||||
i.fa.fa-arrow-right
|
<li onclick="{ parent.move }">
|
||||||
| このフォルダへ移動
|
<p><i class="fa fa-arrow-right"></i>このフォルダへ移動</p>
|
||||||
li(onclick={ parent.new-window }): p
|
</li>
|
||||||
i.fa.fa-share-square-o
|
<li onclick="{ parent.newWindow }">
|
||||||
| 新しいウィンドウで表示
|
<p><i class="fa fa-share-square-o"></i>新しいウィンドウで表示</p>
|
||||||
li.separator
|
</li>
|
||||||
li(onclick={ parent.rename }): p
|
<li class="separator"></li>
|
||||||
i.fa.fa-i-cursor
|
<li onclick="{ parent.rename }">
|
||||||
| 名前を変更
|
<p><i class="fa fa-i-cursor"></i>名前を変更</p>
|
||||||
li.separator
|
</li>
|
||||||
li(onclick={ parent.delete }): p
|
<li class="separator"></li>
|
||||||
i.fa.fa-trash-o
|
<li onclick="{ parent.delete }">
|
||||||
| 削除
|
<p><i class="fa fa-trash-o"></i>削除</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</mk-contextmenu>
|
||||||
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \input-dialog
|
||||||
|
|
||||||
script.
|
@browser = @opts.browser
|
||||||
@mixin \api
|
@folder = @opts.folder
|
||||||
@mixin \input-dialog
|
|
||||||
|
|
||||||
@browser = @opts.browser
|
@open = (pos) ~>
|
||||||
@folder = @opts.folder
|
@refs.ctx.open pos
|
||||||
|
|
||||||
@open = (pos) ~>
|
@refs.ctx.on \closed ~>
|
||||||
@refs.ctx.open pos
|
@trigger \closed
|
||||||
|
@unmount!
|
||||||
|
|
||||||
@refs.ctx.on \closed ~>
|
@move = ~>
|
||||||
@trigger \closed
|
@browser.move @folder.id
|
||||||
@unmount!
|
@refs.ctx.close!
|
||||||
|
|
||||||
@move = ~>
|
@new-window = ~>
|
||||||
@browser.move @folder.id
|
@browser.new-window @folder.id
|
||||||
@refs.ctx.close!
|
@refs.ctx.close!
|
||||||
|
|
||||||
@new-window = ~>
|
@create-folder = ~>
|
||||||
@browser.new-window @folder.id
|
@browser.create-folder!
|
||||||
@refs.ctx.close!
|
@refs.ctx.close!
|
||||||
|
|
||||||
@create-folder = ~>
|
@upload = ~>
|
||||||
@browser.create-folder!
|
@browser.select-lcoal-file!
|
||||||
@refs.ctx.close!
|
@refs.ctx.close!
|
||||||
|
|
||||||
@upload = ~>
|
@rename = ~>
|
||||||
@browser.select-lcoal-file!
|
@refs.ctx.close!
|
||||||
@refs.ctx.close!
|
|
||||||
|
|
||||||
@rename = ~>
|
name <~ @input-dialog do
|
||||||
@refs.ctx.close!
|
'フォルダ名の変更'
|
||||||
|
'新しいフォルダ名を入力してください'
|
||||||
|
@folder.name
|
||||||
|
|
||||||
name <~ @input-dialog do
|
@api \drive/folders/update do
|
||||||
'フォルダ名の変更'
|
folder_id: @folder.id
|
||||||
'新しいフォルダ名を入力してください'
|
name: name
|
||||||
@folder.name
|
.then ~>
|
||||||
|
# something
|
||||||
@api \drive/folders/update do
|
.catch (err) ~>
|
||||||
folder_id: @folder.id
|
console.error err
|
||||||
name: name
|
</script>
|
||||||
.then ~>
|
</mk-drive-browser-folder-contextmenu>
|
||||||
# something
|
|
||||||
.catch (err) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
|
@ -1,183 +1,184 @@
|
||||||
mk-drive-browser-folder(data-is-contextmenu-showing={ is-contextmenu-showing.toString() }, data-draghover={ draghover.toString() }, onclick={ onclick }, onmouseover={ onmouseover }, onmouseout={ onmouseout }, ondragover={ ondragover }, ondragenter={ ondragenter }, ondragleave={ ondragleave }, ondrop={ ondrop }, oncontextmenu={ oncontextmenu }, draggable='true', ondragstart={ ondragstart }, ondragend={ ondragend }, title={ title })
|
<mk-drive-browser-folder data-is-contextmenu-showing="{ isContextmenuShowing.toString() }" data-draghover="{ draghover.toString() }" onclick="{ onclick }" onmouseover="{ onmouseover }" onmouseout="{ onmouseout }" ondragover="{ ondragover }" ondragenter="{ ondragenter }" ondragleave="{ ondragleave }" ondrop="{ ondrop }" oncontextmenu="{ oncontextmenu }" draggable="true" ondragstart="{ ondragstart }" ondragend="{ ondragend }" title="{ title }">
|
||||||
p.name
|
<p class="name"><i class="fa fa-fw { fa-folder-o: !hover, fa-folder-open-o: hover }"></i>{ folder.name }</p>
|
||||||
i.fa.fa-fw(class={ fa-folder-o: !hover, fa-folder-open-o: hover })
|
<style type="stylus">
|
||||||
| { folder.name }
|
:scope
|
||||||
|
display block
|
||||||
style.
|
margin 4px
|
||||||
display block
|
padding 8px
|
||||||
margin 4px
|
width 144px
|
||||||
padding 8px
|
height 64px
|
||||||
width 144px
|
background lighten($theme-color, 95%)
|
||||||
height 64px
|
|
||||||
background lighten($theme-color, 95%)
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&, *
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
*
|
|
||||||
pointer-events none
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background lighten($theme-color, 90%)
|
|
||||||
|
|
||||||
&:active
|
|
||||||
background lighten($theme-color, 85%)
|
|
||||||
|
|
||||||
&[data-is-contextmenu-showing='true']
|
|
||||||
&[data-draghover='true']
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
|
||||||
top -4px
|
|
||||||
right -4px
|
|
||||||
bottom -4px
|
|
||||||
left -4px
|
|
||||||
border 2px dashed rgba($theme-color, 0.3)
|
|
||||||
border-radius 4px
|
border-radius 4px
|
||||||
|
|
||||||
&[data-draghover='true']
|
&, *
|
||||||
background lighten($theme-color, 90%)
|
cursor pointer
|
||||||
|
|
||||||
> .name
|
*
|
||||||
margin 0
|
pointer-events none
|
||||||
font-size 0.9em
|
|
||||||
color darken($theme-color, 30%)
|
|
||||||
|
|
||||||
> i
|
&:hover
|
||||||
margin-right 4px
|
background lighten($theme-color, 90%)
|
||||||
margin-left 2px
|
|
||||||
text-align left
|
|
||||||
|
|
||||||
script.
|
&:active
|
||||||
@mixin \api
|
background lighten($theme-color, 85%)
|
||||||
@mixin \dialog
|
|
||||||
|
|
||||||
@folder = @opts.folder
|
&[data-is-contextmenu-showing='true']
|
||||||
@browser = @parent
|
&[data-draghover='true']
|
||||||
|
&:after
|
||||||
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
position absolute
|
||||||
|
top -4px
|
||||||
|
right -4px
|
||||||
|
bottom -4px
|
||||||
|
left -4px
|
||||||
|
border 2px dashed rgba($theme-color, 0.3)
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
@title = @folder.name
|
&[data-draghover='true']
|
||||||
@hover = false
|
background lighten($theme-color, 90%)
|
||||||
@draghover = false
|
|
||||||
@is-contextmenu-showing = false
|
|
||||||
|
|
||||||
@onclick = ~>
|
> .name
|
||||||
@browser.move @folder
|
margin 0
|
||||||
|
font-size 0.9em
|
||||||
|
color darken($theme-color, 30%)
|
||||||
|
|
||||||
@onmouseover = ~>
|
> i
|
||||||
@hover = true
|
margin-right 4px
|
||||||
|
margin-left 2px
|
||||||
|
text-align left
|
||||||
|
|
||||||
@onmouseout = ~>
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \dialog
|
||||||
|
|
||||||
|
@folder = @opts.folder
|
||||||
|
@browser = @parent
|
||||||
|
|
||||||
|
@title = @folder.name
|
||||||
@hover = false
|
@hover = false
|
||||||
|
@draghover = false
|
||||||
|
@is-contextmenu-showing = false
|
||||||
|
|
||||||
@ondragover = (e) ~>
|
@onclick = ~>
|
||||||
e.prevent-default!
|
@browser.move @folder
|
||||||
e.stop-propagation!
|
|
||||||
|
|
||||||
# 自分自身がドラッグされていない場合
|
@onmouseover = ~>
|
||||||
if !@is-dragging
|
@hover = true
|
||||||
# ドラッグされてきたものがファイルだったら
|
|
||||||
if e.data-transfer.effect-allowed == \all
|
@onmouseout = ~>
|
||||||
e.data-transfer.drop-effect = \copy
|
@hover = false
|
||||||
|
|
||||||
|
@ondragover = (e) ~>
|
||||||
|
e.prevent-default!
|
||||||
|
e.stop-propagation!
|
||||||
|
|
||||||
|
# 自分自身がドラッグされていない場合
|
||||||
|
if !@is-dragging
|
||||||
|
# ドラッグされてきたものがファイルだったら
|
||||||
|
if e.data-transfer.effect-allowed == \all
|
||||||
|
e.data-transfer.drop-effect = \copy
|
||||||
|
else
|
||||||
|
e.data-transfer.drop-effect = \move
|
||||||
else
|
else
|
||||||
e.data-transfer.drop-effect = \move
|
# 自分自身にはドロップさせない
|
||||||
else
|
e.data-transfer.drop-effect = \none
|
||||||
# 自分自身にはドロップさせない
|
|
||||||
e.data-transfer.drop-effect = \none
|
|
||||||
return false
|
|
||||||
|
|
||||||
@ondragenter = ~>
|
|
||||||
if !@is-dragging
|
|
||||||
@draghover = true
|
|
||||||
|
|
||||||
@ondragleave = ~>
|
|
||||||
@draghover = false
|
|
||||||
|
|
||||||
@ondrop = (e) ~>
|
|
||||||
e.stop-propagation!
|
|
||||||
@draghover = false
|
|
||||||
|
|
||||||
# ファイルだったら
|
|
||||||
if e.data-transfer.files.length > 0
|
|
||||||
Array.prototype.for-each.call e.data-transfer.files, (file) ~>
|
|
||||||
@browser.upload file, @folder
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
# データ取得
|
@ondragenter = ~>
|
||||||
data = e.data-transfer.get-data 'text'
|
if !@is-dragging
|
||||||
if !data?
|
@draghover = true
|
||||||
return false
|
|
||||||
|
|
||||||
# パース
|
@ondragleave = ~>
|
||||||
obj = JSON.parse data
|
@draghover = false
|
||||||
|
|
||||||
# (ドライブの)ファイルだったら
|
@ondrop = (e) ~>
|
||||||
if obj.type == \file
|
e.stop-propagation!
|
||||||
file = obj.id
|
@draghover = false
|
||||||
@browser.remove-file file
|
|
||||||
@api \drive/files/update do
|
|
||||||
file_id: file
|
|
||||||
folder_id: @folder.id
|
|
||||||
.then ~>
|
|
||||||
# something
|
|
||||||
.catch (err, text-status) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
# (ドライブの)フォルダーだったら
|
# ファイルだったら
|
||||||
else if obj.type == \folder
|
if e.data-transfer.files.length > 0
|
||||||
folder = obj.id
|
Array.prototype.for-each.call e.data-transfer.files, (file) ~>
|
||||||
# 移動先が自分自身ならreject
|
@browser.upload file, @folder
|
||||||
if folder == @folder.id
|
|
||||||
return false
|
return false
|
||||||
@browser.remove-folder folder
|
|
||||||
@api \drive/folders/update do
|
|
||||||
folder_id: folder
|
|
||||||
parent_id: @folder.id
|
|
||||||
.then ~>
|
|
||||||
# something
|
|
||||||
.catch (err) ~>
|
|
||||||
if err == 'detected-circular-definition'
|
|
||||||
@dialog do
|
|
||||||
'<i class="fa fa-exclamation-triangle"></i>操作を完了できません'
|
|
||||||
'移動先のフォルダーは、移動するフォルダーのサブフォルダーです。'
|
|
||||||
[
|
|
||||||
text: \OK
|
|
||||||
]
|
|
||||||
|
|
||||||
return false
|
# データ取得
|
||||||
|
data = e.data-transfer.get-data 'text'
|
||||||
|
if !data?
|
||||||
|
return false
|
||||||
|
|
||||||
@ondragstart = (e) ~>
|
# パース
|
||||||
e.data-transfer.effect-allowed = \move
|
obj = JSON.parse data
|
||||||
e.data-transfer.set-data 'text' JSON.stringify do
|
|
||||||
type: \folder
|
|
||||||
id: @folder.id
|
|
||||||
@is-dragging = true
|
|
||||||
|
|
||||||
# 親ブラウザに対して、ドラッグが開始されたフラグを立てる
|
# (ドライブの)ファイルだったら
|
||||||
# (=あなたの子供が、ドラッグを開始しましたよ)
|
if obj.type == \file
|
||||||
@browser.is-drag-source = true
|
file = obj.id
|
||||||
|
@browser.remove-file file
|
||||||
|
@api \drive/files/update do
|
||||||
|
file_id: file
|
||||||
|
folder_id: @folder.id
|
||||||
|
.then ~>
|
||||||
|
# something
|
||||||
|
.catch (err, text-status) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
@ondragend = (e) ~>
|
# (ドライブの)フォルダーだったら
|
||||||
@is-dragging = false
|
else if obj.type == \folder
|
||||||
@browser.is-drag-source = false
|
folder = obj.id
|
||||||
|
# 移動先が自分自身ならreject
|
||||||
|
if folder == @folder.id
|
||||||
|
return false
|
||||||
|
@browser.remove-folder folder
|
||||||
|
@api \drive/folders/update do
|
||||||
|
folder_id: folder
|
||||||
|
parent_id: @folder.id
|
||||||
|
.then ~>
|
||||||
|
# something
|
||||||
|
.catch (err) ~>
|
||||||
|
if err == 'detected-circular-definition'
|
||||||
|
@dialog do
|
||||||
|
'<i class="fa fa-exclamation-triangle"></i>操作を完了できません'
|
||||||
|
'移動先のフォルダーは、移動するフォルダーのサブフォルダーです。'
|
||||||
|
[
|
||||||
|
text: \OK
|
||||||
|
]
|
||||||
|
|
||||||
@oncontextmenu = (e) ~>
|
return false
|
||||||
e.prevent-default!
|
|
||||||
e.stop-immediate-propagation!
|
|
||||||
|
|
||||||
@is-contextmenu-showing = true
|
@ondragstart = (e) ~>
|
||||||
@update!
|
e.data-transfer.effect-allowed = \move
|
||||||
ctx = document.body.append-child document.create-element \mk-drive-browser-folder-contextmenu
|
e.data-transfer.set-data 'text' JSON.stringify do
|
||||||
ctx = riot.mount ctx, do
|
type: \folder
|
||||||
browser: @browser
|
id: @folder.id
|
||||||
folder: @folder
|
@is-dragging = true
|
||||||
ctx = ctx.0
|
|
||||||
ctx.open do
|
# 親ブラウザに対して、ドラッグが開始されたフラグを立てる
|
||||||
x: e.page-x - window.page-x-offset
|
# (=あなたの子供が、ドラッグを開始しましたよ)
|
||||||
y: e.page-y - window.page-y-offset
|
@browser.is-drag-source = true
|
||||||
ctx.on \closed ~>
|
|
||||||
@is-contextmenu-showing = false
|
@ondragend = (e) ~>
|
||||||
|
@is-dragging = false
|
||||||
|
@browser.is-drag-source = false
|
||||||
|
|
||||||
|
@oncontextmenu = (e) ~>
|
||||||
|
e.prevent-default!
|
||||||
|
e.stop-immediate-propagation!
|
||||||
|
|
||||||
|
@is-contextmenu-showing = true
|
||||||
@update!
|
@update!
|
||||||
|
ctx = document.body.append-child document.create-element \mk-drive-browser-folder-contextmenu
|
||||||
|
ctx = riot.mount ctx, do
|
||||||
|
browser: @browser
|
||||||
|
folder: @folder
|
||||||
|
ctx = ctx.0
|
||||||
|
ctx.open do
|
||||||
|
x: e.page-x - window.page-x-offset
|
||||||
|
y: e.page-y - window.page-y-offset
|
||||||
|
ctx.on \closed ~>
|
||||||
|
@is-contextmenu-showing = false
|
||||||
|
@update!
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
</script>
|
||||||
|
</mk-drive-browser-folder>
|
||||||
|
|
|
@ -1,96 +1,97 @@
|
||||||
mk-drive-browser-nav-folder(data-draghover={ draghover }, onclick={ onclick }, ondragover={ ondragover }, ondragenter={ ondragenter }, ondragleave={ ondragleave }, ondrop={ ondrop })
|
<mk-drive-browser-nav-folder data-draghover="{ draghover }" onclick="{ onclick }" ondragover="{ ondragover }" ondragenter="{ ondragenter }" ondragleave="{ ondragleave }" ondrop="{ ondrop }"><i class="fa fa-cloud" if="{ folder == null }"></i><span>{ folder == null ? 'ドライブ' : folder.name }</span>
|
||||||
i.fa.fa-cloud(if={ folder == null })
|
<style type="stylus">
|
||||||
span { folder == null ? 'ドライブ' : folder.name }
|
:scope
|
||||||
|
&[data-draghover]
|
||||||
|
background #eee
|
||||||
|
|
||||||
style.
|
</style>
|
||||||
&[data-draghover]
|
<script>
|
||||||
background #eee
|
@mixin \api
|
||||||
|
|
||||||
script.
|
# Riotのバグでnullを渡しても""になる
|
||||||
@mixin \api
|
# https://github.com/riot/riot/issues/2080
|
||||||
|
#@folder = @opts.folder
|
||||||
|
@folder = if @opts.folder? and @opts.folder != '' then @opts.folder else null
|
||||||
|
@browser = @parent
|
||||||
|
|
||||||
# Riotのバグでnullを渡しても""になる
|
|
||||||
# https://github.com/riot/riot/issues/2080
|
|
||||||
#@folder = @opts.folder
|
|
||||||
@folder = if @opts.folder? and @opts.folder != '' then @opts.folder else null
|
|
||||||
@browser = @parent
|
|
||||||
|
|
||||||
@hover = false
|
|
||||||
|
|
||||||
@onclick = ~>
|
|
||||||
@browser.move @folder
|
|
||||||
|
|
||||||
@onmouseover = ~>
|
|
||||||
@hover = true
|
|
||||||
|
|
||||||
@onmouseout = ~>
|
|
||||||
@hover = false
|
@hover = false
|
||||||
|
|
||||||
@ondragover = (e) ~>
|
@onclick = ~>
|
||||||
e.prevent-default!
|
@browser.move @folder
|
||||||
e.stop-propagation!
|
|
||||||
|
|
||||||
# このフォルダがルートかつカレントディレクトリならドロップ禁止
|
@onmouseover = ~>
|
||||||
if @folder == null and @browser.folder == null
|
@hover = true
|
||||||
e.data-transfer.drop-effect = \none
|
|
||||||
# ドラッグされてきたものがファイルだったら
|
|
||||||
else if e.data-transfer.effect-allowed == \all
|
|
||||||
e.data-transfer.drop-effect = \copy
|
|
||||||
else
|
|
||||||
e.data-transfer.drop-effect = \move
|
|
||||||
return false
|
|
||||||
|
|
||||||
@ondragenter = ~>
|
@onmouseout = ~>
|
||||||
if @folder != null or @browser.folder != null
|
@hover = false
|
||||||
@draghover = true
|
|
||||||
|
|
||||||
@ondragleave = ~>
|
@ondragover = (e) ~>
|
||||||
if @folder != null or @browser.folder != null
|
e.prevent-default!
|
||||||
|
e.stop-propagation!
|
||||||
|
|
||||||
|
# このフォルダがルートかつカレントディレクトリならドロップ禁止
|
||||||
|
if @folder == null and @browser.folder == null
|
||||||
|
e.data-transfer.drop-effect = \none
|
||||||
|
# ドラッグされてきたものがファイルだったら
|
||||||
|
else if e.data-transfer.effect-allowed == \all
|
||||||
|
e.data-transfer.drop-effect = \copy
|
||||||
|
else
|
||||||
|
e.data-transfer.drop-effect = \move
|
||||||
|
return false
|
||||||
|
|
||||||
|
@ondragenter = ~>
|
||||||
|
if @folder != null or @browser.folder != null
|
||||||
|
@draghover = true
|
||||||
|
|
||||||
|
@ondragleave = ~>
|
||||||
|
if @folder != null or @browser.folder != null
|
||||||
|
@draghover = false
|
||||||
|
|
||||||
|
@ondrop = (e) ~>
|
||||||
|
e.stop-propagation!
|
||||||
@draghover = false
|
@draghover = false
|
||||||
|
|
||||||
@ondrop = (e) ~>
|
# ファイルだったら
|
||||||
e.stop-propagation!
|
if e.data-transfer.files.length > 0
|
||||||
@draghover = false
|
Array.prototype.for-each.call e.data-transfer.files, (file) ~>
|
||||||
|
@browser.upload file, @folder
|
||||||
# ファイルだったら
|
|
||||||
if e.data-transfer.files.length > 0
|
|
||||||
Array.prototype.for-each.call e.data-transfer.files, (file) ~>
|
|
||||||
@browser.upload file, @folder
|
|
||||||
return false
|
|
||||||
|
|
||||||
# データ取得
|
|
||||||
data = e.data-transfer.get-data 'text'
|
|
||||||
if !data?
|
|
||||||
return false
|
|
||||||
|
|
||||||
# パース
|
|
||||||
obj = JSON.parse data
|
|
||||||
|
|
||||||
# (ドライブの)ファイルだったら
|
|
||||||
if obj.type == \file
|
|
||||||
file = obj.id
|
|
||||||
@browser.remove-file file
|
|
||||||
@api \drive/files/update do
|
|
||||||
file_id: file
|
|
||||||
folder_id: if @folder? then @folder.id else null
|
|
||||||
.then ~>
|
|
||||||
# something
|
|
||||||
.catch (err, text-status) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
# (ドライブの)フォルダーだったら
|
|
||||||
else if obj.type == \folder
|
|
||||||
folder = obj.id
|
|
||||||
# 移動先が自分自身ならreject
|
|
||||||
if @folder? and folder == @folder.id
|
|
||||||
return false
|
return false
|
||||||
@browser.remove-folder folder
|
|
||||||
@api \drive/folders/update do
|
|
||||||
folder_id: folder
|
|
||||||
parent_id: if @folder? then @folder.id else null
|
|
||||||
.then ~>
|
|
||||||
# something
|
|
||||||
.catch (err, text-status) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
return false
|
# データ取得
|
||||||
|
data = e.data-transfer.get-data 'text'
|
||||||
|
if !data?
|
||||||
|
return false
|
||||||
|
|
||||||
|
# パース
|
||||||
|
obj = JSON.parse data
|
||||||
|
|
||||||
|
# (ドライブの)ファイルだったら
|
||||||
|
if obj.type == \file
|
||||||
|
file = obj.id
|
||||||
|
@browser.remove-file file
|
||||||
|
@api \drive/files/update do
|
||||||
|
file_id: file
|
||||||
|
folder_id: if @folder? then @folder.id else null
|
||||||
|
.then ~>
|
||||||
|
# something
|
||||||
|
.catch (err, text-status) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
|
# (ドライブの)フォルダーだったら
|
||||||
|
else if obj.type == \folder
|
||||||
|
folder = obj.id
|
||||||
|
# 移動先が自分自身ならreject
|
||||||
|
if @folder? and folder == @folder.id
|
||||||
|
return false
|
||||||
|
@browser.remove-folder folder
|
||||||
|
@api \drive/folders/update do
|
||||||
|
folder_id: folder
|
||||||
|
parent_id: if @folder? then @folder.id else null
|
||||||
|
.then ~>
|
||||||
|
# something
|
||||||
|
.catch (err, text-status) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
|
return false
|
||||||
|
</script>
|
||||||
|
</mk-drive-browser-nav-folder>
|
||||||
|
|
|
@ -1,34 +1,41 @@
|
||||||
mk-ellipsis-icon
|
<mk-ellipsis-icon>
|
||||||
div
|
<div></div>
|
||||||
div
|
<div></div>
|
||||||
div
|
<div></div>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
width 70px
|
||||||
|
margin 0 auto
|
||||||
|
text-align center
|
||||||
|
|
||||||
style.
|
> div
|
||||||
display block
|
display inline-block
|
||||||
width 70px
|
width 18px
|
||||||
margin 0 auto
|
height 18px
|
||||||
text-align center
|
background-color rgba(0, 0, 0, 0.3)
|
||||||
|
border-radius 100%
|
||||||
|
animation bounce 1.4s infinite ease-in-out both
|
||||||
|
|
||||||
> div
|
&:nth-child(1)
|
||||||
display inline-block
|
animation-delay 0s
|
||||||
width 18px
|
|
||||||
height 18px
|
|
||||||
background-color rgba(0, 0, 0, 0.3)
|
|
||||||
border-radius 100%
|
|
||||||
animation bounce 1.4s infinite ease-in-out both
|
|
||||||
|
|
||||||
&:nth-child(1)
|
&:nth-child(2)
|
||||||
animation-delay 0s
|
margin 0 6px
|
||||||
|
animation-delay 0.16s
|
||||||
|
|
||||||
&:nth-child(2)
|
&:nth-child(3)
|
||||||
margin 0 6px
|
animation-delay 0.32s
|
||||||
animation-delay 0.16s
|
|
||||||
|
|
||||||
&:nth-child(3)
|
@keyframes bounce
|
||||||
animation-delay 0.32s
|
0%, 80%, 100%
|
||||||
|
transform scale(0)
|
||||||
|
40%
|
||||||
|
transform scale(1)
|
||||||
|
|
||||||
@keyframes bounce
|
|
||||||
0%, 80%, 100%
|
|
||||||
transform scale(0)
|
|
||||||
40%
|
|
||||||
transform scale(1)
|
</style>
|
||||||
|
</mk-ellipsis-icon>
|
||||||
|
|
|
@ -1,127 +1,124 @@
|
||||||
mk-follow-button
|
<mk-follow-button>
|
||||||
button(if={ !init }, class={ wait: wait, follow: !user.is_following, unfollow: user.is_following },
|
<button class="{ wait: wait, follow: !user.is_following, unfollow: user.is_following }" if="{ !init }" onclick="{ onclick }" disabled="{ wait }" title="{ user.is_following ? 'フォロー解除' : 'フォローする' }"><i class="fa fa-minus" if="{ !wait && user.is_following }"></i><i class="fa fa-plus" if="{ !wait && !user.is_following }"></i><i class="fa fa-spinner fa-pulse fa-fw" if="{ wait }"></i></button>
|
||||||
onclick={ onclick },
|
<div class="init" if="{ init }"><i class="fa fa-spinner fa-pulse fa-fw"></i></div>
|
||||||
disabled={ wait },
|
<style type="stylus">
|
||||||
title={ user.is_following ? 'フォロー解除' : 'フォローする' })
|
:scope
|
||||||
i.fa.fa-minus(if={ !wait && user.is_following })
|
display block
|
||||||
i.fa.fa-plus(if={ !wait && !user.is_following })
|
|
||||||
i.fa.fa-spinner.fa-pulse.fa-fw(if={ wait })
|
|
||||||
div.init(if={ init }): i.fa.fa-spinner.fa-pulse.fa-fw
|
|
||||||
|
|
||||||
style.
|
> button
|
||||||
display block
|
> .init
|
||||||
|
display block
|
||||||
|
cursor pointer
|
||||||
|
padding 0
|
||||||
|
margin 0
|
||||||
|
width 32px
|
||||||
|
height 32px
|
||||||
|
font-size 1em
|
||||||
|
outline none
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
> button
|
*
|
||||||
> .init
|
pointer-events none
|
||||||
display block
|
|
||||||
cursor pointer
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
width 32px
|
|
||||||
height 32px
|
|
||||||
font-size 1em
|
|
||||||
outline none
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
*
|
&:focus
|
||||||
pointer-events none
|
&:after
|
||||||
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
position absolute
|
||||||
|
top -5px
|
||||||
|
right -5px
|
||||||
|
bottom -5px
|
||||||
|
left -5px
|
||||||
|
border 2px solid rgba($theme-color, 0.3)
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
&:focus
|
&.follow
|
||||||
&:after
|
color #888
|
||||||
content ""
|
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
||||||
pointer-events none
|
border solid 1px #e2e2e2
|
||||||
position absolute
|
|
||||||
top -5px
|
|
||||||
right -5px
|
|
||||||
bottom -5px
|
|
||||||
left -5px
|
|
||||||
border 2px solid rgba($theme-color, 0.3)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
&.follow
|
&:hover
|
||||||
color #888
|
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
||||||
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
border-color #dcdcdc
|
||||||
border solid 1px #e2e2e2
|
|
||||||
|
|
||||||
&:hover
|
&:active
|
||||||
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
background #ececec
|
||||||
border-color #dcdcdc
|
border-color #dcdcdc
|
||||||
|
|
||||||
&:active
|
&.unfollow
|
||||||
background #ececec
|
color $theme-color-foreground
|
||||||
border-color #dcdcdc
|
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
||||||
|
border solid 1px lighten($theme-color, 15%)
|
||||||
|
|
||||||
&.unfollow
|
&:not(:disabled)
|
||||||
color $theme-color-foreground
|
font-weight bold
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
|
||||||
border solid 1px lighten($theme-color, 15%)
|
|
||||||
|
|
||||||
&:not(:disabled)
|
&:hover:not(:disabled)
|
||||||
font-weight bold
|
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
||||||
|
border-color $theme-color
|
||||||
|
|
||||||
&:hover:not(:disabled)
|
&:active:not(:disabled)
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
background $theme-color
|
||||||
border-color $theme-color
|
border-color $theme-color
|
||||||
|
|
||||||
&:active:not(:disabled)
|
&.wait
|
||||||
background $theme-color
|
cursor wait !important
|
||||||
border-color $theme-color
|
opacity 0.7
|
||||||
|
|
||||||
&.wait
|
</style>
|
||||||
cursor wait !important
|
<script>
|
||||||
opacity 0.7
|
@mixin \api
|
||||||
|
@mixin \is-promise
|
||||||
|
@mixin \stream
|
||||||
|
|
||||||
script.
|
@user = null
|
||||||
@mixin \api
|
@user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
|
||||||
@mixin \is-promise
|
@init = true
|
||||||
@mixin \stream
|
@wait = false
|
||||||
|
|
||||||
@user = null
|
@on \mount ~>
|
||||||
@user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user
|
@user-promise.then (user) ~>
|
||||||
@init = true
|
@user = user
|
||||||
@wait = false
|
@init = false
|
||||||
|
|
||||||
@on \mount ~>
|
|
||||||
@user-promise.then (user) ~>
|
|
||||||
@user = user
|
|
||||||
@init = false
|
|
||||||
@update!
|
|
||||||
@stream.on \follow @on-stream-follow
|
|
||||||
@stream.on \unfollow @on-stream-unfollow
|
|
||||||
|
|
||||||
@on \unmount ~>
|
|
||||||
@stream.off \follow @on-stream-follow
|
|
||||||
@stream.off \unfollow @on-stream-unfollow
|
|
||||||
|
|
||||||
@on-stream-follow = (user) ~>
|
|
||||||
if user.id == @user.id
|
|
||||||
@user = user
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@on-stream-unfollow = (user) ~>
|
|
||||||
if user.id == @user.id
|
|
||||||
@user = user
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@onclick = ~>
|
|
||||||
@wait = true
|
|
||||||
if @user.is_following
|
|
||||||
@api \following/delete do
|
|
||||||
user_id: @user.id
|
|
||||||
.then ~>
|
|
||||||
@user.is_following = false
|
|
||||||
.catch (err) ->
|
|
||||||
console.error err
|
|
||||||
.then ~>
|
|
||||||
@wait = false
|
|
||||||
@update!
|
@update!
|
||||||
else
|
@stream.on \follow @on-stream-follow
|
||||||
@api \following/create do
|
@stream.on \unfollow @on-stream-unfollow
|
||||||
user_id: @user.id
|
|
||||||
.then ~>
|
@on \unmount ~>
|
||||||
@user.is_following = true
|
@stream.off \follow @on-stream-follow
|
||||||
.catch (err) ->
|
@stream.off \unfollow @on-stream-unfollow
|
||||||
console.error err
|
|
||||||
.then ~>
|
@on-stream-follow = (user) ~>
|
||||||
@wait = false
|
if user.id == @user.id
|
||||||
|
@user = user
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
|
@on-stream-unfollow = (user) ~>
|
||||||
|
if user.id == @user.id
|
||||||
|
@user = user
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@onclick = ~>
|
||||||
|
@wait = true
|
||||||
|
if @user.is_following
|
||||||
|
@api \following/delete do
|
||||||
|
user_id: @user.id
|
||||||
|
.then ~>
|
||||||
|
@user.is_following = false
|
||||||
|
.catch (err) ->
|
||||||
|
console.error err
|
||||||
|
.then ~>
|
||||||
|
@wait = false
|
||||||
|
@update!
|
||||||
|
else
|
||||||
|
@api \following/create do
|
||||||
|
user_id: @user.id
|
||||||
|
.then ~>
|
||||||
|
@user.is_following = true
|
||||||
|
.catch (err) ->
|
||||||
|
console.error err
|
||||||
|
.then ~>
|
||||||
|
@wait = false
|
||||||
|
@update!
|
||||||
|
</script>
|
||||||
|
</mk-follow-button>
|
||||||
|
|
|
@ -1,163 +1,163 @@
|
||||||
mk-following-setuper
|
<mk-following-setuper>
|
||||||
p.title 気になるユーザーをフォロー:
|
<p class="title">気になるユーザーをフォロー:</p>
|
||||||
div.users(if={ !loading && users.length > 0 })
|
<div class="users" if="{ !loading && users.length > 0 }">
|
||||||
div.user(each={ users })
|
<div class="user" each="{ users }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + username }"><img class="avatar" src="{ avatar_url + '?thumbnail&size=42' }" alt="" data-user-preview="{ id }"/></a>
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + username })
|
<div class="body"><a class="name" href="{ CONFIG.url + '/' + username }" target="_blank" data-user-preview="{ id }">{ name }</a>
|
||||||
img.avatar(src={ avatar_url + '?thumbnail&size=42' }, alt='', data-user-preview={ id })
|
<p class="username">@{ username }</p>
|
||||||
div.body
|
</div>
|
||||||
a.name(href={ CONFIG.url + '/' + username }, target='_blank', data-user-preview={ id }) { name }
|
<mk-follow-button user="{ this }"></mk-follow-button>
|
||||||
p.username @{ username }
|
</div>
|
||||||
mk-follow-button(user={ this })
|
</div>
|
||||||
p.empty(if={ !loading && users.length == 0 })
|
<p class="empty" if="{ !loading && users.length == 0 }">おすすめのユーザーは見つかりませんでした。</p>
|
||||||
| おすすめのユーザーは見つかりませんでした。
|
<p class="loading" if="{ loading }"><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
|
||||||
p.loading(if={ loading })
|
<mk-ellipsis></mk-ellipsis>
|
||||||
i.fa.fa-spinner.fa-pulse.fa-fw
|
</p><a class="refresh" onclick="{ refresh }">もっと見る</a>
|
||||||
| 読み込んでいます
|
<button class="close" onclick="{ close }" title="閉じる"><i class="fa fa-times"></i></button>
|
||||||
mk-ellipsis
|
<style type="stylus">
|
||||||
a.refresh(onclick={ refresh }) もっと見る
|
:scope
|
||||||
button.close(onclick={ close }, title='閉じる'): i.fa.fa-times
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
padding 24px
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
> .title
|
|
||||||
margin 0 0 12px 0
|
|
||||||
font-size 1em
|
|
||||||
font-weight bold
|
|
||||||
color #888
|
|
||||||
|
|
||||||
> .users
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
display block
|
||||||
clear both
|
padding 24px
|
||||||
|
background #fff
|
||||||
|
|
||||||
> .user
|
> .title
|
||||||
padding 16px
|
margin 0 0 12px 0
|
||||||
width 238px
|
font-size 1em
|
||||||
float left
|
font-weight bold
|
||||||
|
color #888
|
||||||
|
|
||||||
&:after
|
> .users
|
||||||
content ""
|
&:after
|
||||||
display block
|
content ""
|
||||||
clear both
|
|
||||||
|
|
||||||
> .avatar-anchor
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
margin 0 12px 0 0
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
display block
|
||||||
width 42px
|
clear both
|
||||||
height 42px
|
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .body
|
> .user
|
||||||
float left
|
padding 16px
|
||||||
width calc(100% - 54px)
|
width 238px
|
||||||
|
float left
|
||||||
|
|
||||||
> .name
|
&:after
|
||||||
margin 0
|
content ""
|
||||||
font-size 16px
|
display block
|
||||||
line-height 24px
|
clear both
|
||||||
|
|
||||||
|
> .avatar-anchor
|
||||||
|
display block
|
||||||
|
float left
|
||||||
|
margin 0 12px 0 0
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
display block
|
||||||
|
width 42px
|
||||||
|
height 42px
|
||||||
|
margin 0
|
||||||
|
border-radius 8px
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
|
> .body
|
||||||
|
float left
|
||||||
|
width calc(100% - 54px)
|
||||||
|
|
||||||
|
> .name
|
||||||
|
margin 0
|
||||||
|
font-size 16px
|
||||||
|
line-height 24px
|
||||||
|
color #555
|
||||||
|
|
||||||
|
> .username
|
||||||
|
margin 0
|
||||||
|
font-size 15px
|
||||||
|
line-height 16px
|
||||||
|
color #ccc
|
||||||
|
|
||||||
|
> mk-follow-button
|
||||||
|
position absolute
|
||||||
|
top 16px
|
||||||
|
right 16px
|
||||||
|
|
||||||
|
> .empty
|
||||||
|
margin 0
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color #aaa
|
||||||
|
|
||||||
|
> .loading
|
||||||
|
margin 0
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color #aaa
|
||||||
|
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
|
> .refresh
|
||||||
|
display block
|
||||||
|
margin 0 8px 0 0
|
||||||
|
text-align right
|
||||||
|
font-size 0.9em
|
||||||
|
color #999
|
||||||
|
|
||||||
|
> .close
|
||||||
|
cursor pointer
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top 6px
|
||||||
|
right 6px
|
||||||
|
z-index 1
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
font-size 1.2em
|
||||||
|
color #999
|
||||||
|
border none
|
||||||
|
outline none
|
||||||
|
background transparent
|
||||||
|
|
||||||
|
&:hover
|
||||||
color #555
|
color #555
|
||||||
|
|
||||||
> .username
|
&:active
|
||||||
margin 0
|
color #222
|
||||||
font-size 15px
|
|
||||||
line-height 16px
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
> mk-follow-button
|
> i
|
||||||
position absolute
|
padding 14px
|
||||||
top 16px
|
|
||||||
right 16px
|
|
||||||
|
|
||||||
> .empty
|
</style>
|
||||||
margin 0
|
<script>
|
||||||
padding 16px
|
@mixin \api
|
||||||
text-align center
|
@mixin \user-preview
|
||||||
color #aaa
|
|
||||||
|
|
||||||
> .loading
|
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
text-align center
|
|
||||||
color #aaa
|
|
||||||
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
> .refresh
|
|
||||||
display block
|
|
||||||
margin 0 8px 0 0
|
|
||||||
text-align right
|
|
||||||
font-size 0.9em
|
|
||||||
color #999
|
|
||||||
|
|
||||||
> .close
|
|
||||||
cursor pointer
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 6px
|
|
||||||
right 6px
|
|
||||||
z-index 1
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
font-size 1.2em
|
|
||||||
color #999
|
|
||||||
border none
|
|
||||||
outline none
|
|
||||||
background transparent
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color #555
|
|
||||||
|
|
||||||
&:active
|
|
||||||
color #222
|
|
||||||
|
|
||||||
> i
|
|
||||||
padding 14px
|
|
||||||
|
|
||||||
script.
|
|
||||||
@mixin \api
|
|
||||||
@mixin \user-preview
|
|
||||||
|
|
||||||
@users = null
|
|
||||||
@loading = true
|
|
||||||
|
|
||||||
@limit = 6users
|
|
||||||
@page = 0
|
|
||||||
|
|
||||||
@on \mount ~>
|
|
||||||
@load!
|
|
||||||
|
|
||||||
@load = ~>
|
|
||||||
@loading = true
|
|
||||||
@users = null
|
@users = null
|
||||||
@update!
|
@loading = true
|
||||||
|
|
||||||
@api \users/recommendation do
|
@limit = 6users
|
||||||
limit: @limit
|
@page = 0
|
||||||
offset: @limit * @page
|
|
||||||
.then (users) ~>
|
@on \mount ~>
|
||||||
@loading = false
|
@load!
|
||||||
@users = users
|
|
||||||
|
@load = ~>
|
||||||
|
@loading = true
|
||||||
|
@users = null
|
||||||
@update!
|
@update!
|
||||||
.catch (err, text-status) ->
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@refresh = ~>
|
@api \users/recommendation do
|
||||||
if @users.length < @limit
|
limit: @limit
|
||||||
@page = 0
|
offset: @limit * @page
|
||||||
else
|
.then (users) ~>
|
||||||
@page++
|
@loading = false
|
||||||
@load!
|
@users = users
|
||||||
|
@update!
|
||||||
|
.catch (err, text-status) ->
|
||||||
|
console.error err
|
||||||
|
|
||||||
@close = ~>
|
@refresh = ~>
|
||||||
@unmount!
|
if @users.length < @limit
|
||||||
|
@page = 0
|
||||||
|
else
|
||||||
|
@page++
|
||||||
|
@load!
|
||||||
|
|
||||||
|
@close = ~>
|
||||||
|
@unmount!
|
||||||
|
</script>
|
||||||
|
</mk-following-setuper>
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
mk-go-top
|
<mk-go-top>
|
||||||
button.hidden(title='一番上へ')
|
<button class="hidden" title="一番上へ"><i class="fa fa-angle-up"></i></button>
|
||||||
i.fa.fa-angle-up
|
<script>
|
||||||
|
window.add-event-listener \load @on-scroll
|
||||||
|
window.add-event-listener \scroll @on-scroll
|
||||||
|
window.add-event-listener \resize @on-scroll
|
||||||
|
|
||||||
script.
|
@on-scroll = ~>
|
||||||
|
if $ window .scroll-top! > 500px
|
||||||
window.add-event-listener \load @on-scroll
|
@remove-class \hidden
|
||||||
window.add-event-listener \scroll @on-scroll
|
else
|
||||||
window.add-event-listener \resize @on-scroll
|
@add-class \hidden
|
||||||
|
</script>
|
||||||
@on-scroll = ~>
|
</mk-go-top>
|
||||||
if $ window .scroll-top! > 500px
|
|
||||||
@remove-class \hidden
|
|
||||||
else
|
|
||||||
@add-class \hidden
|
|
||||||
|
|
|
@ -1,75 +1,83 @@
|
||||||
mk-broadcast-home-widget
|
<mk-broadcast-home-widget>
|
||||||
div.icon
|
<div class="icon">
|
||||||
svg(height='32', version='1.1', viewBox='0 0 32 32', width='32')
|
<svg height="32" version="1.1" viewBox="0 0 32 32" width="32">
|
||||||
path.tower(d='M16.04,11.24c1.79,0,3.239-1.45,3.239-3.24S17.83,4.76,16.04,4.76c-1.79,0-3.24,1.45-3.24,3.24 C12.78,9.78,14.24,11.24,16.04,11.24z M16.04,13.84c-0.82,0-1.66-0.2-2.4-0.6L7.34,29.98h2.98l1.72-2h8l1.681,2H24.7L18.42,13.24 C17.66,13.64,16.859,13.84,16.04,13.84z M16.02,14.8l2.02,7.2h-4L16.02,14.8z M12.04,25.98l2-2h4l2,2H12.04z')
|
<path class="tower" d="M16.04,11.24c1.79,0,3.239-1.45,3.239-3.24S17.83,4.76,16.04,4.76c-1.79,0-3.24,1.45-3.24,3.24 C12.78,9.78,14.24,11.24,16.04,11.24z M16.04,13.84c-0.82,0-1.66-0.2-2.4-0.6L7.34,29.98h2.98l1.72-2h8l1.681,2H24.7L18.42,13.24 C17.66,13.64,16.859,13.84,16.04,13.84z M16.02,14.8l2.02,7.2h-4L16.02,14.8z M12.04,25.98l2-2h4l2,2H12.04z"></path>
|
||||||
path.wave.a(d='M4.66,1.04c-0.508-0.508-1.332-0.508-1.84,0c-1.86,1.92-2.8,4.44-2.8,6.94c0,2.52,0.94,5.04,2.8,6.96 c0.5,0.52,1.32,0.52,1.82,0s0.5-1.36,0-1.88C3.28,11.66,2.6,9.82,2.6,7.98S3.28,4.3,4.64,2.9C5.157,2.391,5.166,1.56,4.66,1.04z')
|
<path class="wave a" d="M4.66,1.04c-0.508-0.508-1.332-0.508-1.84,0c-1.86,1.92-2.8,4.44-2.8,6.94c0,2.52,0.94,5.04,2.8,6.96 c0.5,0.52,1.32,0.52,1.82,0s0.5-1.36,0-1.88C3.28,11.66,2.6,9.82,2.6,7.98S3.28,4.3,4.64,2.9C5.157,2.391,5.166,1.56,4.66,1.04z"></path>
|
||||||
path.wave.b(d='M9.58,12.22c0.5-0.5,0.5-1.34,0-1.84C8.94,9.72,8.62,8.86,8.62,8s0.32-1.72,0.96-2.38c0.5-0.52,0.5-1.34,0-1.84 C9.346,3.534,9.02,3.396,8.68,3.4c-0.32,0-0.66,0.12-0.9,0.38C6.64,4.94,6.08,6.48,6.08,8s0.58,3.06,1.7,4.22 C8.28,12.72,9.1,12.72,9.58,12.22z')
|
<path class="wave b" d="M9.58,12.22c0.5-0.5,0.5-1.34,0-1.84C8.94,9.72,8.62,8.86,8.62,8s0.32-1.72,0.96-2.38c0.5-0.52,0.5-1.34,0-1.84 C9.346,3.534,9.02,3.396,8.68,3.4c-0.32,0-0.66,0.12-0.9,0.38C6.64,4.94,6.08,6.48,6.08,8s0.58,3.06,1.7,4.22 C8.28,12.72,9.1,12.72,9.58,12.22z"></path>
|
||||||
path.wave.c(d='M22.42,3.78c-0.5,0.5-0.5,1.34,0,1.84c0.641,0.66,0.96,1.52,0.96,2.38s-0.319,1.72-0.96,2.38c-0.5,0.52-0.5,1.34,0,1.84 c0.487,0.497,1.285,0.505,1.781,0.018c0.007-0.006,0.013-0.012,0.02-0.018c1.139-1.16,1.699-2.7,1.699-4.22s-0.561-3.06-1.699-4.22 c-0.494-0.497-1.297-0.5-1.794-0.007C22.424,3.775,22.422,3.778,22.42,3.78z')
|
<path class="wave c" d="M22.42,3.78c-0.5,0.5-0.5,1.34,0,1.84c0.641,0.66,0.96,1.52,0.96,2.38s-0.319,1.72-0.96,2.38c-0.5,0.52-0.5,1.34,0,1.84 c0.487,0.497,1.285,0.505,1.781,0.018c0.007-0.006,0.013-0.012,0.02-0.018c1.139-1.16,1.699-2.7,1.699-4.22s-0.561-3.06-1.699-4.22 c-0.494-0.497-1.297-0.5-1.794-0.007C22.424,3.775,22.422,3.778,22.42,3.78z"></path>
|
||||||
path.wave.d(d='M29.18,1.06c-0.479-0.502-1.273-0.522-1.775-0.044c-0.016,0.015-0.029,0.029-0.045,0.044c-0.5,0.52-0.5,1.36,0,1.88 c1.361,1.4,2.041,3.24,2.041,5.08s-0.68,3.66-2.041,5.08c-0.5,0.52-0.5,1.36,0,1.88c0.509,0.508,1.332,0.508,1.841,0 c1.86-1.92,2.8-4.44,2.8-6.96C31.99,5.424,30.98,2.931,29.18,1.06z')
|
<path class="wave d" d="M29.18,1.06c-0.479-0.502-1.273-0.522-1.775-0.044c-0.016,0.015-0.029,0.029-0.045,0.044c-0.5,0.52-0.5,1.36,0,1.88 c1.361,1.4,2.041,3.24,2.041,5.08s-0.68,3.66-2.041,5.08c-0.5,0.52-0.5,1.36,0,1.88c0.509,0.508,1.332,0.508,1.841,0 c1.86-1.92,2.8-4.44,2.8-6.96C31.99,5.424,30.98,2.931,29.18,1.06z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h1>開発者募集中!</h1>
|
||||||
|
<p><a href="https://github.com/syuilo/misskey" target="_blank">Misskeyはオープンソースで開発されています。リポジトリはこちら。</a></p>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
padding 10px 10px 10px 50px
|
||||||
|
background transparent
|
||||||
|
border-color #4078c0 !important
|
||||||
|
|
||||||
h1 開発者募集中!
|
&:after
|
||||||
p: a(href='https://github.com/syuilo/misskey', target='_blank') Misskeyはオープンソースで開発されています。リポジトリはこちら。
|
content ""
|
||||||
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
style.
|
> .icon
|
||||||
display block
|
display block
|
||||||
padding 10px 10px 10px 50px
|
float left
|
||||||
background transparent
|
margin-left -40px
|
||||||
border-color #4078c0 !important
|
|
||||||
|
|
||||||
&:after
|
> svg
|
||||||
content ""
|
fill currentColor
|
||||||
display block
|
color #4078c0
|
||||||
clear both
|
|
||||||
|
|
||||||
> .icon
|
> .wave
|
||||||
display block
|
|
||||||
float left
|
|
||||||
margin-left -40px
|
|
||||||
|
|
||||||
> svg
|
|
||||||
fill currentColor
|
|
||||||
color #4078c0
|
|
||||||
|
|
||||||
> .wave
|
|
||||||
opacity 1
|
|
||||||
|
|
||||||
&.a
|
|
||||||
animation wave 20s ease-in-out 2.1s infinite
|
|
||||||
&.b
|
|
||||||
animation wave 20s ease-in-out 2s infinite
|
|
||||||
&.c
|
|
||||||
animation wave 20s ease-in-out 2s infinite
|
|
||||||
&.d
|
|
||||||
animation wave 20s ease-in-out 2.1s infinite
|
|
||||||
|
|
||||||
@keyframes wave
|
|
||||||
0%
|
|
||||||
opacity 1
|
|
||||||
1.5%
|
|
||||||
opacity 0
|
|
||||||
3.5%
|
|
||||||
opacity 0
|
|
||||||
5%
|
|
||||||
opacity 1
|
|
||||||
6.5%
|
|
||||||
opacity 0
|
|
||||||
8.5%
|
|
||||||
opacity 0
|
|
||||||
10%
|
|
||||||
opacity 1
|
opacity 1
|
||||||
|
|
||||||
> h1
|
&.a
|
||||||
margin 0
|
animation wave 20s ease-in-out 2.1s infinite
|
||||||
font-size 0.95em
|
&.b
|
||||||
font-weight normal
|
animation wave 20s ease-in-out 2s infinite
|
||||||
color #4078c0
|
&.c
|
||||||
|
animation wave 20s ease-in-out 2s infinite
|
||||||
|
&.d
|
||||||
|
animation wave 20s ease-in-out 2.1s infinite
|
||||||
|
|
||||||
> p
|
@keyframes wave
|
||||||
display block
|
0%
|
||||||
z-index 1
|
opacity 1
|
||||||
margin 0
|
1.5%
|
||||||
font-size 0.7em
|
opacity 0
|
||||||
color #555
|
3.5%
|
||||||
|
opacity 0
|
||||||
|
5%
|
||||||
|
opacity 1
|
||||||
|
6.5%
|
||||||
|
opacity 0
|
||||||
|
8.5%
|
||||||
|
opacity 0
|
||||||
|
10%
|
||||||
|
opacity 1
|
||||||
|
|
||||||
a
|
> h1
|
||||||
color #555
|
margin 0
|
||||||
|
font-size 0.95em
|
||||||
|
font-weight normal
|
||||||
|
color #4078c0
|
||||||
|
|
||||||
|
> p
|
||||||
|
display block
|
||||||
|
z-index 1
|
||||||
|
margin 0
|
||||||
|
font-size 0.7em
|
||||||
|
color #555
|
||||||
|
|
||||||
|
a
|
||||||
|
color #555
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</mk-broadcast-home-widget>
|
||||||
|
|
|
@ -1,147 +1,148 @@
|
||||||
mk-calendar-home-widget(data-special={ special })
|
<mk-calendar-home-widget data-special="{ special }">
|
||||||
div.calendar(data-is-holiday={ is-holiday })
|
<div class="calendar" data-is-holiday="{ isHoliday }">
|
||||||
p.month-and-year
|
<p class="month-and-year"><span class="year">{ year }年</span><span class="month">{ month }月</span></p>
|
||||||
span.year { year }年
|
<p class="day">{ day }日</p>
|
||||||
span.month { month }月
|
<p class="week-day">{ weekDay }曜日</p>
|
||||||
p.day { day }日
|
</div>
|
||||||
p.week-day { week-day }曜日
|
<div class="info">
|
||||||
div.info
|
<div>
|
||||||
div
|
<p>今日:<b>{ dayP.toFixed(1) }%</b></p>
|
||||||
p
|
<div class="meter">
|
||||||
| 今日:
|
<div class="val" style="{ 'width:' + dayP + '%' }"></div>
|
||||||
b { day-p.to-fixed(1) }%
|
</div>
|
||||||
div.meter
|
</div>
|
||||||
div.val(style={ 'width:' + day-p + '%' })
|
<div>
|
||||||
|
<p>今月:<b>{ monthP.toFixed(1) }%</b></p>
|
||||||
|
<div class="meter">
|
||||||
|
<div class="val" style="{ 'width:' + monthP + '%' }"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>今年:<b>{ yearP.toFixed(1) }%</b></p>
|
||||||
|
<div class="meter">
|
||||||
|
<div class="val" style="{ 'width:' + yearP + '%' }"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
padding 16px 0
|
||||||
|
color #777
|
||||||
|
background #fff
|
||||||
|
|
||||||
div
|
&[data-special='on-new-years-day']
|
||||||
p
|
border-color #ef95a0 !important
|
||||||
| 今月:
|
|
||||||
b { month-p.to-fixed(1) }%
|
|
||||||
div.meter
|
|
||||||
div.val(style={ 'width:' + month-p + '%' })
|
|
||||||
|
|
||||||
div
|
&:after
|
||||||
p
|
content ""
|
||||||
| 今年:
|
display block
|
||||||
b { year-p.to-fixed(1) }%
|
clear both
|
||||||
div.meter
|
|
||||||
div.val(style={ 'width:' + year-p + '%' })
|
|
||||||
|
|
||||||
style.
|
> .calendar
|
||||||
display block
|
float left
|
||||||
padding 16px 0
|
width 60%
|
||||||
color #777
|
text-align center
|
||||||
background #fff
|
|
||||||
|
|
||||||
&[data-special='on-new-years-day']
|
&[data-is-holiday]
|
||||||
border-color #ef95a0 !important
|
> .day
|
||||||
|
color #ef95a0
|
||||||
|
|
||||||
&:after
|
> p
|
||||||
content ""
|
margin 0
|
||||||
display block
|
line-height 18px
|
||||||
clear both
|
font-size 14px
|
||||||
|
|
||||||
> .calendar
|
> span
|
||||||
float left
|
margin 0 4px
|
||||||
width 60%
|
|
||||||
text-align center
|
|
||||||
|
|
||||||
&[data-is-holiday]
|
> .day
|
||||||
> .day
|
margin 10px 0
|
||||||
color #ef95a0
|
line-height 32px
|
||||||
|
font-size 28px
|
||||||
|
|
||||||
> p
|
> .info
|
||||||
margin 0
|
display block
|
||||||
line-height 18px
|
float left
|
||||||
font-size 14px
|
width 40%
|
||||||
|
padding 0 16px 0 0
|
||||||
|
|
||||||
> span
|
> div
|
||||||
margin 0 4px
|
margin-bottom 8px
|
||||||
|
|
||||||
> .day
|
&:last-child
|
||||||
margin 10px 0
|
margin-bottom 4px
|
||||||
line-height 32px
|
|
||||||
font-size 28px
|
|
||||||
|
|
||||||
> .info
|
> p
|
||||||
display block
|
margin 0 0 2px 0
|
||||||
float left
|
font-size 12px
|
||||||
width 40%
|
line-height 18px
|
||||||
padding 0 16px 0 0
|
color #888
|
||||||
|
|
||||||
> div
|
> b
|
||||||
margin-bottom 8px
|
margin-left 2px
|
||||||
|
|
||||||
&:last-child
|
> .meter
|
||||||
margin-bottom 4px
|
width 100%
|
||||||
|
overflow hidden
|
||||||
|
background #eee
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
> p
|
> .val
|
||||||
margin 0 0 2px 0
|
height 4px
|
||||||
font-size 12px
|
background $theme-color
|
||||||
line-height 18px
|
|
||||||
color #888
|
|
||||||
|
|
||||||
> b
|
&:nth-child(1)
|
||||||
margin-left 2px
|
> .meter > .val
|
||||||
|
background #f7796c
|
||||||
|
|
||||||
> .meter
|
&:nth-child(2)
|
||||||
width 100%
|
> .meter > .val
|
||||||
overflow hidden
|
background #a1de41
|
||||||
background #eee
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
> .val
|
&:nth-child(3)
|
||||||
height 4px
|
> .meter > .val
|
||||||
background $theme-color
|
background #41ddde
|
||||||
|
|
||||||
&:nth-child(1)
|
</style>
|
||||||
> .meter > .val
|
<script>
|
||||||
background #f7796c
|
@draw = ~>
|
||||||
|
now = new Date!
|
||||||
|
nd = now.get-date!
|
||||||
|
nm = now.get-month!
|
||||||
|
ny = now.get-full-year!
|
||||||
|
|
||||||
&:nth-child(2)
|
@year = ny
|
||||||
> .meter > .val
|
@month = nm + 1
|
||||||
background #a1de41
|
@day = nd
|
||||||
|
@week-day = [\日 \月 \火 \水 \木 \金 \土][now.get-day!]
|
||||||
|
|
||||||
&:nth-child(3)
|
@day-numer = (now - (new Date ny, nm, nd))
|
||||||
> .meter > .val
|
@day-denom = 1000ms * 60s * 60m * 24h
|
||||||
background #41ddde
|
@month-numer = (now - (new Date ny, nm, 1))
|
||||||
|
@month-denom = (new Date ny, nm + 1, 1) - (new Date ny, nm, 1)
|
||||||
|
@year-numer = (now - (new Date ny, 0, 1))
|
||||||
|
@year-denom = (new Date ny + 1, 0, 1) - (new Date ny, 0, 1)
|
||||||
|
|
||||||
script.
|
@day-p = @day-numer / @day-denom * 100
|
||||||
@draw = ~>
|
@month-p = @month-numer / @month-denom * 100
|
||||||
now = new Date!
|
@year-p = @year-numer / @year-denom * 100
|
||||||
nd = now.get-date!
|
|
||||||
nm = now.get-month!
|
|
||||||
ny = now.get-full-year!
|
|
||||||
|
|
||||||
@year = ny
|
@is-holiday =
|
||||||
@month = nm + 1
|
(now.get-day! == 0 or now.get-day! == 6)
|
||||||
@day = nd
|
|
||||||
@week-day = [\日 \月 \火 \水 \木 \金 \土][now.get-day!]
|
|
||||||
|
|
||||||
@day-numer = (now - (new Date ny, nm, nd))
|
@special =
|
||||||
@day-denom = 1000ms * 60s * 60m * 24h
|
| nm == 0 and nd == 1 => \on-new-years-day
|
||||||
@month-numer = (now - (new Date ny, nm, 1))
|
| _ => false
|
||||||
@month-denom = (new Date ny, nm + 1, 1) - (new Date ny, nm, 1)
|
|
||||||
@year-numer = (now - (new Date ny, 0, 1))
|
|
||||||
@year-denom = (new Date ny + 1, 0, 1) - (new Date ny, 0, 1)
|
|
||||||
|
|
||||||
@day-p = @day-numer / @day-denom * 100
|
@update!
|
||||||
@month-p = @month-numer / @month-denom * 100
|
|
||||||
@year-p = @year-numer / @year-denom * 100
|
|
||||||
|
|
||||||
@is-holiday =
|
@draw!
|
||||||
(now.get-day! == 0 or now.get-day! == 6)
|
|
||||||
|
|
||||||
@special =
|
@on \mount ~>
|
||||||
| nm == 0 and nd == 1 => \on-new-years-day
|
@clock = set-interval @draw, 1000ms
|
||||||
| _ => false
|
|
||||||
|
|
||||||
@update!
|
@on \unmount ~>
|
||||||
|
clear-interval @clock
|
||||||
@draw!
|
</script>
|
||||||
|
</mk-calendar-home-widget>
|
||||||
@on \mount ~>
|
|
||||||
@clock = set-interval @draw, 1000ms
|
|
||||||
|
|
||||||
@on \unmount ~>
|
|
||||||
clear-interval @clock
|
|
||||||
|
|
|
@ -1,37 +1,36 @@
|
||||||
mk-donation-home-widget
|
<mk-donation-home-widget>
|
||||||
article
|
<article>
|
||||||
h1
|
<h1><i class="fa fa-heart"></i>寄付のお願い</h1>
|
||||||
i.fa.fa-heart
|
<p>
|
||||||
| 寄付のお願い
|
Misskeyの運営にはドメイン、サーバー等のコストが掛かります。
|
||||||
p
|
Misskeyは広告を掲載したりしないため、 収入を皆様からの寄付に頼っています。
|
||||||
| Misskeyの運営にはドメイン、サーバー等のコストが掛かります。
|
もしご興味があれば、<a href="/syuilo" data-user-preview="@syuilo">@syuilo</a>までご連絡ください。ご協力ありがとうございます。
|
||||||
| Misskeyは広告を掲載したりしないため、 収入を皆様からの寄付に頼っています。
|
</p>
|
||||||
| もしご興味があれば、
|
</article>
|
||||||
a(href='/syuilo', data-user-preview='@syuilo') @syuilo
|
<style type="stylus">
|
||||||
| までご連絡ください。ご協力ありがとうございます。
|
:scope
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
background #fff
|
|
||||||
border-color #ead8bb !important
|
|
||||||
|
|
||||||
> article
|
|
||||||
padding 20px
|
|
||||||
|
|
||||||
> h1
|
|
||||||
margin 0 0 5px 0
|
|
||||||
font-size 1em
|
|
||||||
color #888
|
|
||||||
|
|
||||||
> i
|
|
||||||
margin-right 0.25em
|
|
||||||
|
|
||||||
> p
|
|
||||||
display block
|
display block
|
||||||
z-index 1
|
background #fff
|
||||||
margin 0
|
border-color #ead8bb !important
|
||||||
font-size 0.8em
|
|
||||||
color #999
|
|
||||||
|
|
||||||
script.
|
> article
|
||||||
@mixin \user-preview
|
padding 20px
|
||||||
|
|
||||||
|
> h1
|
||||||
|
margin 0 0 5px 0
|
||||||
|
font-size 1em
|
||||||
|
color #888
|
||||||
|
|
||||||
|
> i
|
||||||
|
margin-right 0.25em
|
||||||
|
|
||||||
|
> p
|
||||||
|
display block
|
||||||
|
z-index 1
|
||||||
|
margin 0
|
||||||
|
font-size 0.8em
|
||||||
|
color #999
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>@mixin \user-preview</script>
|
||||||
|
</mk-donation-home-widget>
|
||||||
|
|
|
@ -1,117 +1,112 @@
|
||||||
mk-mentions-home-widget
|
<mk-mentions-home-widget>
|
||||||
header
|
<header><span data-is-active="{ mode == 'all' }" onclick="{ setMode.bind(this, 'all') }">すべて</span><span data-is-active="{ mode == 'following' }" onclick="{ setMode.bind(this, 'following') }">フォロー中</span></header>
|
||||||
span(data-is-active={ mode == 'all' }, onclick={ set-mode.bind(this, 'all') }) すべて
|
<div class="loading" if="{ isLoading }">
|
||||||
span(data-is-active={ mode == 'following' }, onclick={ set-mode.bind(this, 'following') }) フォロー中
|
<mk-ellipsis-icon></mk-ellipsis-icon>
|
||||||
div.loading(if={ is-loading })
|
</div>
|
||||||
mk-ellipsis-icon
|
<p class="empty" if="{ isEmpty }"><i class="fa fa-comments-o"></i><span if="{ mode == 'all' }">あなた宛ての投稿はありません。</span><span if="{ mode == 'following' }">あなたがフォローしているユーザーからの言及はありません。</span></p>
|
||||||
p.empty(if={ is-empty })
|
<mk-timeline ref="timeline"><yield to="footer"><i class="fa fa-moon-o" if="{ !parent.moreLoading }"></i><i class="fa fa-spinner fa-pulse fa-fw" if="{ parent.moreLoading }"></i></yield></mk-timeline>
|
||||||
i.fa.fa-comments-o
|
<style type="stylus">
|
||||||
span(if={ mode == 'all' }) あなた宛ての投稿はありません。
|
:scope
|
||||||
span(if={ mode == 'following' }) あなたがフォローしているユーザーからの言及はありません。
|
|
||||||
mk-timeline@timeline
|
|
||||||
<yield to="footer">
|
|
||||||
i.fa.fa-moon-o(if={ !parent.more-loading })
|
|
||||||
i.fa.fa-spinner.fa-pulse.fa-fw(if={ parent.more-loading })
|
|
||||||
</yield>
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
> header
|
|
||||||
padding 8px 16px
|
|
||||||
border-bottom solid 1px #eee
|
|
||||||
|
|
||||||
> span
|
|
||||||
margin-right 16px
|
|
||||||
line-height 27px
|
|
||||||
font-size 18px
|
|
||||||
color #555
|
|
||||||
|
|
||||||
&:not([data-is-active])
|
|
||||||
color $theme-color
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
> .loading
|
|
||||||
padding 64px 0
|
|
||||||
|
|
||||||
> .empty
|
|
||||||
display block
|
|
||||||
margin 0 auto
|
|
||||||
padding 32px
|
|
||||||
max-width 400px
|
|
||||||
text-align center
|
|
||||||
color #999
|
|
||||||
|
|
||||||
> i
|
|
||||||
display block
|
display block
|
||||||
margin-bottom 16px
|
background #fff
|
||||||
font-size 3em
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
script.
|
> header
|
||||||
@mixin \i
|
padding 8px 16px
|
||||||
@mixin \api
|
border-bottom solid 1px #eee
|
||||||
|
|
||||||
@is-loading = true
|
> span
|
||||||
@is-empty = false
|
margin-right 16px
|
||||||
@more-loading = false
|
line-height 27px
|
||||||
@mode = \all
|
font-size 18px
|
||||||
|
color #555
|
||||||
|
|
||||||
@on \mount ~>
|
&:not([data-is-active])
|
||||||
document.add-event-listener \keydown @on-document-keydown
|
color $theme-color
|
||||||
window.add-event-listener \scroll @on-scroll
|
cursor pointer
|
||||||
|
|
||||||
@fetch ~>
|
&:hover
|
||||||
@trigger \loaded
|
text-decoration underline
|
||||||
|
|
||||||
@on \unmount ~>
|
> .loading
|
||||||
document.remove-event-listener \keydown @on-document-keydown
|
padding 64px 0
|
||||||
window.remove-event-listener \scroll @on-scroll
|
|
||||||
|
|
||||||
@on-document-keydown = (e) ~>
|
> .empty
|
||||||
tag = e.target.tag-name.to-lower-case!
|
display block
|
||||||
if tag != \input and tag != \textarea
|
margin 0 auto
|
||||||
if e.which == 84 # t
|
padding 32px
|
||||||
@refs.timeline.focus!
|
max-width 400px
|
||||||
|
text-align center
|
||||||
|
color #999
|
||||||
|
|
||||||
@fetch = (cb) ~>
|
> i
|
||||||
@api \posts/mentions do
|
display block
|
||||||
following: @mode == \following
|
margin-bottom 16px
|
||||||
.then (posts) ~>
|
font-size 3em
|
||||||
@is-loading = false
|
color #ccc
|
||||||
@is-empty = posts.length == 0
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mixin \api
|
||||||
|
|
||||||
|
@is-loading = true
|
||||||
|
@is-empty = false
|
||||||
|
@more-loading = false
|
||||||
|
@mode = \all
|
||||||
|
|
||||||
|
@on \mount ~>
|
||||||
|
document.add-event-listener \keydown @on-document-keydown
|
||||||
|
window.add-event-listener \scroll @on-scroll
|
||||||
|
|
||||||
|
@fetch ~>
|
||||||
|
@trigger \loaded
|
||||||
|
|
||||||
|
@on \unmount ~>
|
||||||
|
document.remove-event-listener \keydown @on-document-keydown
|
||||||
|
window.remove-event-listener \scroll @on-scroll
|
||||||
|
|
||||||
|
@on-document-keydown = (e) ~>
|
||||||
|
tag = e.target.tag-name.to-lower-case!
|
||||||
|
if tag != \input and tag != \textarea
|
||||||
|
if e.which == 84 # t
|
||||||
|
@refs.timeline.focus!
|
||||||
|
|
||||||
|
@fetch = (cb) ~>
|
||||||
|
@api \posts/mentions do
|
||||||
|
following: @mode == \following
|
||||||
|
.then (posts) ~>
|
||||||
|
@is-loading = false
|
||||||
|
@is-empty = posts.length == 0
|
||||||
|
@update!
|
||||||
|
@refs.timeline.set-posts posts
|
||||||
|
if cb? then cb!
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
if cb? then cb!
|
||||||
|
|
||||||
|
@more = ~>
|
||||||
|
if @more-loading or @is-loading or @refs.timeline.posts.length == 0
|
||||||
|
return
|
||||||
|
@more-loading = true
|
||||||
@update!
|
@update!
|
||||||
@refs.timeline.set-posts posts
|
@api \posts/mentions do
|
||||||
if cb? then cb!
|
following: @mode == \following
|
||||||
.catch (err) ~>
|
max_id: @refs.timeline.tail!.id
|
||||||
console.error err
|
.then (posts) ~>
|
||||||
if cb? then cb!
|
@more-loading = false
|
||||||
|
@update!
|
||||||
|
@refs.timeline.prepend-posts posts
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
@more = ~>
|
@on-scroll = ~>
|
||||||
if @more-loading or @is-loading or @refs.timeline.posts.length == 0
|
current = window.scroll-y + window.inner-height
|
||||||
return
|
if current > document.body.offset-height - 8
|
||||||
@more-loading = true
|
@more!
|
||||||
@update!
|
|
||||||
@api \posts/mentions do
|
|
||||||
following: @mode == \following
|
|
||||||
max_id: @refs.timeline.tail!.id
|
|
||||||
.then (posts) ~>
|
|
||||||
@more-loading = false
|
|
||||||
@update!
|
|
||||||
@refs.timeline.prepend-posts posts
|
|
||||||
.catch (err) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@on-scroll = ~>
|
@set-mode = (mode) ~>
|
||||||
current = window.scroll-y + window.inner-height
|
@update do
|
||||||
if current > document.body.offset-height - 8
|
mode: mode
|
||||||
@more!
|
@fetch!
|
||||||
|
</script>
|
||||||
@set-mode = (mode) ~>
|
</mk-mentions-home-widget>
|
||||||
@update do
|
|
||||||
mode: mode
|
|
||||||
@fetch!
|
|
||||||
|
|
|
@ -1,23 +1,21 @@
|
||||||
mk-nav-home-widget
|
<mk-nav-home-widget><a href="{ CONFIG.urls.about }">Misskeyについて</a><i>・</i><a href="{ CONFIG.urls.about + '/status' }">ステータス</a><i>・</i><a href="https://github.com/syuilo/misskey">リポジトリ</a><i>・</i><a href="{ CONFIG.urls.dev }">開発者</a><i>・</i><a href="https://twitter.com/misskey_xyz" target="_blank">Follow us on <i class="fa fa-twitter"></i></a>
|
||||||
a(href={ CONFIG.urls.about }) Misskeyについて
|
<style type="stylus">
|
||||||
i ・
|
:scope
|
||||||
a(href={ CONFIG.urls.about + '/status' }) ステータス
|
display block
|
||||||
i ・
|
padding 16px
|
||||||
a(href='https://github.com/syuilo/misskey') リポジトリ
|
font-size 12px
|
||||||
i ・
|
color #aaa
|
||||||
a(href={ CONFIG.urls.dev }) 開発者
|
background #fff
|
||||||
i ・
|
|
||||||
a(href='https://twitter.com/misskey_xyz', target='_blank') Follow us on <i class="fa fa-twitter"></i>
|
|
||||||
|
|
||||||
style.
|
a
|
||||||
display block
|
color #999
|
||||||
padding 16px
|
|
||||||
font-size 12px
|
|
||||||
color #aaa
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
a
|
i
|
||||||
color #999
|
color #ccc
|
||||||
|
|
||||||
i
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</mk-nav-home-widget>
|
||||||
|
|
|
@ -1,49 +1,50 @@
|
||||||
mk-notifications-home-widget
|
<mk-notifications-home-widget>
|
||||||
p.title
|
<p class="title"><i class="fa fa-bell-o"></i>通知</p>
|
||||||
i.fa.fa-bell-o
|
<button onclick="{ settings }" title="通知の設定"><i class="fa fa-cog"></i></button>
|
||||||
| 通知
|
<mk-notifications></mk-notifications>
|
||||||
button(onclick={ settings }, title='通知の設定'): i.fa.fa-cog
|
<style type="stylus">
|
||||||
mk-notifications
|
:scope
|
||||||
|
display block
|
||||||
|
background #fff
|
||||||
|
|
||||||
style.
|
> .title
|
||||||
display block
|
z-index 1
|
||||||
background #fff
|
margin 0
|
||||||
|
padding 0 16px
|
||||||
|
line-height 42px
|
||||||
|
font-size 0.9em
|
||||||
|
font-weight bold
|
||||||
|
color #888
|
||||||
|
box-shadow 0 1px rgba(0, 0, 0, 0.07)
|
||||||
|
|
||||||
> .title
|
> i
|
||||||
z-index 1
|
margin-right 4px
|
||||||
margin 0
|
|
||||||
padding 0 16px
|
|
||||||
line-height 42px
|
|
||||||
font-size 0.9em
|
|
||||||
font-weight bold
|
|
||||||
color #888
|
|
||||||
box-shadow 0 1px rgba(0, 0, 0, 0.07)
|
|
||||||
|
|
||||||
> i
|
> button
|
||||||
margin-right 4px
|
position absolute
|
||||||
|
z-index 2
|
||||||
|
top 0
|
||||||
|
right 0
|
||||||
|
padding 0
|
||||||
|
width 42px
|
||||||
|
font-size 0.9em
|
||||||
|
line-height 42px
|
||||||
|
color #ccc
|
||||||
|
|
||||||
> button
|
&:hover
|
||||||
position absolute
|
color #aaa
|
||||||
z-index 2
|
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
padding 0
|
|
||||||
width 42px
|
|
||||||
font-size 0.9em
|
|
||||||
line-height 42px
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
&:hover
|
&:active
|
||||||
color #aaa
|
color #999
|
||||||
|
|
||||||
&:active
|
> mk-notifications
|
||||||
color #999
|
max-height 300px
|
||||||
|
overflow auto
|
||||||
|
|
||||||
> mk-notifications
|
</style>
|
||||||
max-height 300px
|
<script>
|
||||||
overflow auto
|
@settings = ~>
|
||||||
|
w = riot.mount document.body.append-child document.create-element \mk-settings-window .0
|
||||||
script.
|
w.switch \notification
|
||||||
@settings = ~>
|
</script>
|
||||||
w = riot.mount document.body.append-child document.create-element \mk-settings-window .0
|
</mk-notifications-home-widget>
|
||||||
w.switch \notification
|
|
||||||
|
|
|
@ -1,86 +1,87 @@
|
||||||
mk-photo-stream-home-widget
|
<mk-photo-stream-home-widget>
|
||||||
p.title
|
<p class="title"><i class="fa fa-camera"></i>フォトストリーム</p>
|
||||||
i.fa.fa-camera
|
<p class="initializing" if="{ initializing }"><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
|
||||||
| フォトストリーム
|
<mk-ellipsis></mk-ellipsis>
|
||||||
p.initializing(if={ initializing })
|
</p>
|
||||||
i.fa.fa-spinner.fa-pulse.fa-fw
|
<div class="stream" if="{ !initializing && images.length > 0 }">
|
||||||
| 読み込んでいます
|
<virtual each="{ image in images }">
|
||||||
mk-ellipsis
|
<div class="img" style="{ 'background-image: url(' + image.url + '?thumbnail&size=256)' }"></div>
|
||||||
div.stream(if={ !initializing && images.length > 0 })
|
</virtual>
|
||||||
virtual(each={ image in images })
|
</div>
|
||||||
div.img(style={ 'background-image: url(' + image.url + '?thumbnail&size=256)' })
|
<p class="empty" if="{ !initializing && images.length == 0 }">写真はありません</p>
|
||||||
p.empty(if={ !initializing && images.length == 0 })
|
<style type="stylus">
|
||||||
| 写真はありません
|
:scope
|
||||||
|
display block
|
||||||
|
background #fff
|
||||||
|
|
||||||
style.
|
> .title
|
||||||
display block
|
z-index 1
|
||||||
background #fff
|
margin 0
|
||||||
|
padding 0 16px
|
||||||
|
line-height 42px
|
||||||
|
font-size 0.9em
|
||||||
|
font-weight bold
|
||||||
|
color #888
|
||||||
|
box-shadow 0 1px rgba(0, 0, 0, 0.07)
|
||||||
|
|
||||||
> .title
|
> i
|
||||||
z-index 1
|
margin-right 4px
|
||||||
margin 0
|
|
||||||
padding 0 16px
|
|
||||||
line-height 42px
|
|
||||||
font-size 0.9em
|
|
||||||
font-weight bold
|
|
||||||
color #888
|
|
||||||
box-shadow 0 1px rgba(0, 0, 0, 0.07)
|
|
||||||
|
|
||||||
> i
|
> .stream
|
||||||
margin-right 4px
|
display -webkit-flex
|
||||||
|
display -moz-flex
|
||||||
|
display -ms-flex
|
||||||
|
display flex
|
||||||
|
justify-content center
|
||||||
|
flex-wrap wrap
|
||||||
|
padding 8px
|
||||||
|
|
||||||
> .stream
|
> .img
|
||||||
display -webkit-flex
|
flex 1 1 33%
|
||||||
display -moz-flex
|
width 33%
|
||||||
display -ms-flex
|
height 80px
|
||||||
display flex
|
background-position center center
|
||||||
justify-content center
|
background-size cover
|
||||||
flex-wrap wrap
|
background-clip content-box
|
||||||
padding 8px
|
border solid 2px transparent
|
||||||
|
|
||||||
> .img
|
> .initializing
|
||||||
flex 1 1 33%
|
> .empty
|
||||||
width 33%
|
margin 0
|
||||||
height 80px
|
padding 16px
|
||||||
background-position center center
|
text-align center
|
||||||
background-size cover
|
color #aaa
|
||||||
background-clip content-box
|
|
||||||
border solid 2px transparent
|
|
||||||
|
|
||||||
> .initializing
|
> i
|
||||||
> .empty
|
margin-right 4px
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
text-align center
|
|
||||||
color #aaa
|
|
||||||
|
|
||||||
> i
|
</style>
|
||||||
margin-right 4px
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \stream
|
||||||
|
|
||||||
script.
|
@images = []
|
||||||
@mixin \api
|
@initializing = true
|
||||||
@mixin \stream
|
|
||||||
|
|
||||||
@images = []
|
@on \mount ~>
|
||||||
@initializing = true
|
@stream.on \drive_file_created @on-stream-drive-file-created
|
||||||
|
|
||||||
@on \mount ~>
|
@api \drive/stream do
|
||||||
@stream.on \drive_file_created @on-stream-drive-file-created
|
type: 'image/*'
|
||||||
|
limit: 9images
|
||||||
|
.then (images) ~>
|
||||||
|
@initializing = false
|
||||||
|
@images = images
|
||||||
|
@update!
|
||||||
|
|
||||||
@api \drive/stream do
|
@on \unmount ~>
|
||||||
type: 'image/*'
|
@stream.off \drive_file_created @on-stream-drive-file-created
|
||||||
limit: 9images
|
|
||||||
.then (images) ~>
|
|
||||||
@initializing = false
|
|
||||||
@images = images
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@on \unmount ~>
|
@on-stream-drive-file-created = (file) ~>
|
||||||
@stream.off \drive_file_created @on-stream-drive-file-created
|
if /^image\/.+$/.test file.type
|
||||||
|
@images.unshift file
|
||||||
@on-stream-drive-file-created = (file) ~>
|
if @images.length > 9
|
||||||
if /^image\/.+$/.test file.type
|
@images.pop!
|
||||||
@images.unshift file
|
@update!
|
||||||
if @images.length > 9
|
</script>
|
||||||
@images.pop!
|
</mk-photo-stream-home-widget>
|
||||||
@update!
|
|
||||||
|
|
|
@ -1,55 +1,56 @@
|
||||||
mk-profile-home-widget
|
<mk-profile-home-widget>
|
||||||
div.banner(style={ I.banner_url ? 'background-image: url(' + I.banner_url + '?thumbnail&size=256)' : '' }, onclick={ set-banner })
|
<div class="banner" style="{ I.banner_url ? 'background-image: url(' + I.banner_url + '?thumbnail&size=256)' : '' }" onclick="{ setBanner }"></div><img class="avatar" src="{ I.avatar_url + '?thumbnail&size=64' }" onclick="{ setAvatar }" alt="avatar" data-user-preview="{ I.id }"/><a class="name" href="{ CONFIG.url + '/' + I.username }">{ I.name }</a>
|
||||||
img.avatar(src={ I.avatar_url + '?thumbnail&size=64' }, onclick={ set-avatar }, alt='avatar', data-user-preview={ I.id })
|
<p class="username">@{ I.username }</p>
|
||||||
a.name(href={ CONFIG.url + '/' + I.username }) { I.name }
|
<style type="stylus">
|
||||||
p.username @{ I.username }
|
:scope
|
||||||
|
display block
|
||||||
|
background #fff
|
||||||
|
|
||||||
style.
|
> .banner
|
||||||
display block
|
height 100px
|
||||||
background #fff
|
background-color #f5f5f5
|
||||||
|
background-size cover
|
||||||
|
background-position center
|
||||||
|
|
||||||
> .banner
|
> .avatar
|
||||||
height 100px
|
display block
|
||||||
background-color #f5f5f5
|
position absolute
|
||||||
background-size cover
|
top 76px
|
||||||
background-position center
|
left 16px
|
||||||
|
width 58px
|
||||||
|
height 58px
|
||||||
|
margin 0
|
||||||
|
border solid 3px #fff
|
||||||
|
border-radius 8px
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
> .avatar
|
> .name
|
||||||
display block
|
display block
|
||||||
position absolute
|
margin 10px 0 0 92px
|
||||||
top 76px
|
line-height 16px
|
||||||
left 16px
|
font-weight bold
|
||||||
width 58px
|
color #555
|
||||||
height 58px
|
|
||||||
margin 0
|
|
||||||
border solid 3px #fff
|
|
||||||
border-radius 8px
|
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .name
|
> .username
|
||||||
display block
|
display block
|
||||||
margin 10px 0 0 92px
|
margin 4px 0 8px 92px
|
||||||
line-height 16px
|
line-height 16px
|
||||||
font-weight bold
|
font-size 0.9em
|
||||||
color #555
|
color #999
|
||||||
|
|
||||||
> .username
|
</style>
|
||||||
display block
|
<script>
|
||||||
margin 4px 0 8px 92px
|
@mixin \i
|
||||||
line-height 16px
|
@mixin \user-preview
|
||||||
font-size 0.9em
|
@mixin \update-avatar
|
||||||
color #999
|
@mixin \update-banner
|
||||||
|
|
||||||
script.
|
@set-avatar = ~>
|
||||||
@mixin \i
|
@update-avatar @I, (i) ~>
|
||||||
@mixin \user-preview
|
@update-i i
|
||||||
@mixin \update-avatar
|
|
||||||
@mixin \update-banner
|
|
||||||
|
|
||||||
@set-avatar = ~>
|
@set-banner = ~>
|
||||||
@update-avatar @I, (i) ~>
|
@update-banner @I, (i) ~>
|
||||||
@update-i i
|
@update-i i
|
||||||
|
</script>
|
||||||
@set-banner = ~>
|
</mk-profile-home-widget>
|
||||||
@update-banner @I, (i) ~>
|
|
||||||
@update-i i
|
|
||||||
|
|
|
@ -1,94 +1,94 @@
|
||||||
mk-rss-reader-home-widget
|
<mk-rss-reader-home-widget>
|
||||||
p.title
|
<p class="title"><i class="fa fa-rss-square"></i>RSS</p>
|
||||||
i.fa.fa-rss-square
|
<button onclick="{ settings }" title="設定"><i class="fa fa-cog"></i></button>
|
||||||
| RSS
|
<div class="feed" if="{ !initializing }">
|
||||||
button(onclick={ settings }, title='設定'): i.fa.fa-cog
|
<virtual each="{ item in items }"><a href="{ item.link }" target="_blank">{ item.title }</a></virtual>
|
||||||
div.feed(if={ !initializing })
|
</div>
|
||||||
virtual(each={ item in items })
|
<p class="initializing" if="{ initializing }"><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
|
||||||
a(href={ item.link }, target='_blank') { item.title }
|
<mk-ellipsis></mk-ellipsis>
|
||||||
p.initializing(if={ initializing })
|
</p>
|
||||||
i.fa.fa-spinner.fa-pulse.fa-fw
|
<style type="stylus">
|
||||||
| 読み込んでいます
|
:scope
|
||||||
mk-ellipsis
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
> .title
|
|
||||||
margin 0
|
|
||||||
padding 0 16px
|
|
||||||
line-height 42px
|
|
||||||
font-size 0.9em
|
|
||||||
font-weight bold
|
|
||||||
color #888
|
|
||||||
box-shadow 0 1px rgba(0, 0, 0, 0.07)
|
|
||||||
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
> button
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
padding 0
|
|
||||||
width 42px
|
|
||||||
font-size 0.9em
|
|
||||||
line-height 42px
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color #aaa
|
|
||||||
|
|
||||||
&:active
|
|
||||||
color #999
|
|
||||||
|
|
||||||
> .feed
|
|
||||||
padding 12px 16px
|
|
||||||
font-size 0.9em
|
|
||||||
|
|
||||||
> a
|
|
||||||
display block
|
display block
|
||||||
padding 4px 0
|
background #fff
|
||||||
color #666
|
|
||||||
border-bottom dashed 1px #eee
|
|
||||||
|
|
||||||
&:last-child
|
> .title
|
||||||
border-bottom none
|
margin 0
|
||||||
|
padding 0 16px
|
||||||
|
line-height 42px
|
||||||
|
font-size 0.9em
|
||||||
|
font-weight bold
|
||||||
|
color #888
|
||||||
|
box-shadow 0 1px rgba(0, 0, 0, 0.07)
|
||||||
|
|
||||||
> .initializing
|
> i
|
||||||
margin 0
|
margin-right 4px
|
||||||
padding 16px
|
|
||||||
text-align center
|
|
||||||
color #aaa
|
|
||||||
|
|
||||||
> i
|
> button
|
||||||
margin-right 4px
|
position absolute
|
||||||
|
top 0
|
||||||
|
right 0
|
||||||
|
padding 0
|
||||||
|
width 42px
|
||||||
|
font-size 0.9em
|
||||||
|
line-height 42px
|
||||||
|
color #ccc
|
||||||
|
|
||||||
script.
|
&:hover
|
||||||
@mixin \api
|
color #aaa
|
||||||
@mixin \NotImplementedException
|
|
||||||
|
|
||||||
@url = 'http://news.yahoo.co.jp/pickup/rss.xml'
|
&:active
|
||||||
@items = []
|
color #999
|
||||||
@initializing = true
|
|
||||||
|
|
||||||
@on \mount ~>
|
> .feed
|
||||||
@fetch!
|
padding 12px 16px
|
||||||
@clock = set-interval @fetch, 60000ms
|
font-size 0.9em
|
||||||
|
|
||||||
@on \unmount ~>
|
> a
|
||||||
clear-interval @clock
|
display block
|
||||||
|
padding 4px 0
|
||||||
|
color #666
|
||||||
|
border-bottom dashed 1px #eee
|
||||||
|
|
||||||
@fetch = ~>
|
&:last-child
|
||||||
@api CONFIG.url + '/api:rss' do
|
border-bottom none
|
||||||
url: @url
|
|
||||||
.then (feed) ~>
|
|
||||||
@items = feed.rss.channel.item
|
|
||||||
@initializing = false
|
|
||||||
@update!
|
|
||||||
.catch (err) ->
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@settings = ~>
|
> .initializing
|
||||||
@NotImplementedException!
|
margin 0
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color #aaa
|
||||||
|
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \NotImplementedException
|
||||||
|
|
||||||
|
@url = 'http://news.yahoo.co.jp/pickup/rss.xml'
|
||||||
|
@items = []
|
||||||
|
@initializing = true
|
||||||
|
|
||||||
|
@on \mount ~>
|
||||||
|
@fetch!
|
||||||
|
@clock = set-interval @fetch, 60000ms
|
||||||
|
|
||||||
|
@on \unmount ~>
|
||||||
|
clear-interval @clock
|
||||||
|
|
||||||
|
@fetch = ~>
|
||||||
|
@api CONFIG.url + '/api:rss' do
|
||||||
|
url: @url
|
||||||
|
.then (feed) ~>
|
||||||
|
@items = feed.rss.channel.item
|
||||||
|
@initializing = false
|
||||||
|
@update!
|
||||||
|
.catch (err) ->
|
||||||
|
console.error err
|
||||||
|
|
||||||
|
@settings = ~>
|
||||||
|
@NotImplementedException!
|
||||||
|
</script>
|
||||||
|
</mk-rss-reader-home-widget>
|
||||||
|
|
|
@ -1,113 +1,111 @@
|
||||||
mk-timeline-home-widget
|
<mk-timeline-home-widget>
|
||||||
mk-following-setuper(if={ no-following })
|
<mk-following-setuper if="{ noFollowing }"></mk-following-setuper>
|
||||||
div.loading(if={ is-loading })
|
<div class="loading" if="{ isLoading }">
|
||||||
mk-ellipsis-icon
|
<mk-ellipsis-icon></mk-ellipsis-icon>
|
||||||
p.empty(if={ is-empty })
|
</div>
|
||||||
i.fa.fa-comments-o
|
<p class="empty" if="{ isEmpty }"><i class="fa fa-comments-o"></i>自分の投稿や、自分がフォローしているユーザーの投稿が表示されます。</p>
|
||||||
| 自分の投稿や、自分がフォローしているユーザーの投稿が表示されます。
|
<mk-timeline ref="timeline"><yield to="footer"><i class="fa fa-moon-o" if="{ !parent.moreLoading }"></i><i class="fa fa-spinner fa-pulse fa-fw" if="{ parent.moreLoading }"></i></yield></mk-timeline>
|
||||||
mk-timeline@timeline
|
<style type="stylus">
|
||||||
<yield to="footer">
|
:scope
|
||||||
i.fa.fa-moon-o(if={ !parent.more-loading })
|
|
||||||
i.fa.fa-spinner.fa-pulse.fa-fw(if={ parent.more-loading })
|
|
||||||
</yield>
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
> mk-following-setuper
|
|
||||||
border-bottom solid 1px #eee
|
|
||||||
|
|
||||||
> .loading
|
|
||||||
padding 64px 0
|
|
||||||
|
|
||||||
> .empty
|
|
||||||
display block
|
|
||||||
margin 0 auto
|
|
||||||
padding 32px
|
|
||||||
max-width 400px
|
|
||||||
text-align center
|
|
||||||
color #999
|
|
||||||
|
|
||||||
> i
|
|
||||||
display block
|
display block
|
||||||
margin-bottom 16px
|
background #fff
|
||||||
font-size 3em
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
script.
|
> mk-following-setuper
|
||||||
@mixin \i
|
border-bottom solid 1px #eee
|
||||||
@mixin \api
|
|
||||||
@mixin \stream
|
|
||||||
|
|
||||||
@is-loading = true
|
> .loading
|
||||||
@is-empty = false
|
padding 64px 0
|
||||||
@more-loading = false
|
|
||||||
@no-following = @I.following_count == 0
|
|
||||||
|
|
||||||
@on \mount ~>
|
> .empty
|
||||||
@stream.on \post @on-stream-post
|
display block
|
||||||
@stream.on \follow @on-stream-follow
|
margin 0 auto
|
||||||
@stream.on \unfollow @on-stream-unfollow
|
padding 32px
|
||||||
|
max-width 400px
|
||||||
|
text-align center
|
||||||
|
color #999
|
||||||
|
|
||||||
document.add-event-listener \keydown @on-document-keydown
|
> i
|
||||||
window.add-event-listener \scroll @on-scroll
|
display block
|
||||||
|
margin-bottom 16px
|
||||||
|
font-size 3em
|
||||||
|
color #ccc
|
||||||
|
|
||||||
@load ~>
|
</style>
|
||||||
@trigger \loaded
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mixin \api
|
||||||
|
@mixin \stream
|
||||||
|
|
||||||
@on \unmount ~>
|
@is-loading = true
|
||||||
@stream.off \post @on-stream-post
|
|
||||||
@stream.off \follow @on-stream-follow
|
|
||||||
@stream.off \unfollow @on-stream-unfollow
|
|
||||||
|
|
||||||
document.remove-event-listener \keydown @on-document-keydown
|
|
||||||
window.remove-event-listener \scroll @on-scroll
|
|
||||||
|
|
||||||
@on-document-keydown = (e) ~>
|
|
||||||
tag = e.target.tag-name.to-lower-case!
|
|
||||||
if tag != \input and tag != \textarea
|
|
||||||
if e.which == 84 # t
|
|
||||||
@refs.timeline.focus!
|
|
||||||
|
|
||||||
@load = (cb) ~>
|
|
||||||
@api \posts/timeline
|
|
||||||
.then (posts) ~>
|
|
||||||
@is-loading = false
|
|
||||||
@is-empty = posts.length == 0
|
|
||||||
@update!
|
|
||||||
@refs.timeline.set-posts posts
|
|
||||||
if cb? then cb!
|
|
||||||
.catch (err) ~>
|
|
||||||
console.error err
|
|
||||||
if cb? then cb!
|
|
||||||
|
|
||||||
@more = ~>
|
|
||||||
if @more-loading or @is-loading or @refs.timeline.posts.length == 0
|
|
||||||
return
|
|
||||||
@more-loading = true
|
|
||||||
@update!
|
|
||||||
@api \posts/timeline do
|
|
||||||
max_id: @refs.timeline.tail!.id
|
|
||||||
.then (posts) ~>
|
|
||||||
@more-loading = false
|
|
||||||
@update!
|
|
||||||
@refs.timeline.prepend-posts posts
|
|
||||||
.catch (err) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@on-stream-post = (post) ~>
|
|
||||||
@is-empty = false
|
@is-empty = false
|
||||||
@update!
|
@more-loading = false
|
||||||
@refs.timeline.add-post post
|
@no-following = @I.following_count == 0
|
||||||
|
|
||||||
@on-stream-follow = ~>
|
@on \mount ~>
|
||||||
@load!
|
@stream.on \post @on-stream-post
|
||||||
|
@stream.on \follow @on-stream-follow
|
||||||
|
@stream.on \unfollow @on-stream-unfollow
|
||||||
|
|
||||||
@on-stream-unfollow = ~>
|
document.add-event-listener \keydown @on-document-keydown
|
||||||
@load!
|
window.add-event-listener \scroll @on-scroll
|
||||||
|
|
||||||
@on-scroll = ~>
|
@load ~>
|
||||||
current = window.scroll-y + window.inner-height
|
@trigger \loaded
|
||||||
if current > document.body.offset-height - 8
|
|
||||||
@more!
|
@on \unmount ~>
|
||||||
|
@stream.off \post @on-stream-post
|
||||||
|
@stream.off \follow @on-stream-follow
|
||||||
|
@stream.off \unfollow @on-stream-unfollow
|
||||||
|
|
||||||
|
document.remove-event-listener \keydown @on-document-keydown
|
||||||
|
window.remove-event-listener \scroll @on-scroll
|
||||||
|
|
||||||
|
@on-document-keydown = (e) ~>
|
||||||
|
tag = e.target.tag-name.to-lower-case!
|
||||||
|
if tag != \input and tag != \textarea
|
||||||
|
if e.which == 84 # t
|
||||||
|
@refs.timeline.focus!
|
||||||
|
|
||||||
|
@load = (cb) ~>
|
||||||
|
@api \posts/timeline
|
||||||
|
.then (posts) ~>
|
||||||
|
@is-loading = false
|
||||||
|
@is-empty = posts.length == 0
|
||||||
|
@update!
|
||||||
|
@refs.timeline.set-posts posts
|
||||||
|
if cb? then cb!
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
if cb? then cb!
|
||||||
|
|
||||||
|
@more = ~>
|
||||||
|
if @more-loading or @is-loading or @refs.timeline.posts.length == 0
|
||||||
|
return
|
||||||
|
@more-loading = true
|
||||||
|
@update!
|
||||||
|
@api \posts/timeline do
|
||||||
|
max_id: @refs.timeline.tail!.id
|
||||||
|
.then (posts) ~>
|
||||||
|
@more-loading = false
|
||||||
|
@update!
|
||||||
|
@refs.timeline.prepend-posts posts
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
|
@on-stream-post = (post) ~>
|
||||||
|
@is-empty = false
|
||||||
|
@update!
|
||||||
|
@refs.timeline.add-post post
|
||||||
|
|
||||||
|
@on-stream-follow = ~>
|
||||||
|
@load!
|
||||||
|
|
||||||
|
@on-stream-unfollow = ~>
|
||||||
|
@load!
|
||||||
|
|
||||||
|
@on-scroll = ~>
|
||||||
|
current = window.scroll-y + window.inner-height
|
||||||
|
if current > document.body.offset-height - 8
|
||||||
|
@more!
|
||||||
|
</script>
|
||||||
|
</mk-timeline-home-widget>
|
||||||
|
|
|
@ -1,70 +1,71 @@
|
||||||
mk-tips-home-widget
|
<mk-tips-home-widget>
|
||||||
p@tip
|
<p ref="tip"><i class="fa fa-lightbulb-o"></i><span ref="text"></span></p>
|
||||||
i.fa.fa-lightbulb-o
|
<style type="stylus">
|
||||||
span@text
|
:scope
|
||||||
|
display block
|
||||||
|
background transparent !important
|
||||||
|
border none !important
|
||||||
|
overflow visible !important
|
||||||
|
|
||||||
style.
|
> p
|
||||||
display block
|
display block
|
||||||
background transparent !important
|
margin 0
|
||||||
border none !important
|
padding 0 12px
|
||||||
overflow visible !important
|
text-align center
|
||||||
|
font-size 0.7em
|
||||||
|
color #999
|
||||||
|
|
||||||
> p
|
> i
|
||||||
display block
|
margin-right 4px
|
||||||
margin 0
|
|
||||||
padding 0 12px
|
|
||||||
text-align center
|
|
||||||
font-size 0.7em
|
|
||||||
color #999
|
|
||||||
|
|
||||||
> i
|
kbd
|
||||||
margin-right 4px
|
display inline
|
||||||
|
padding 0 6px
|
||||||
|
margin 0 2px
|
||||||
|
font-size 1em
|
||||||
|
font-family inherit
|
||||||
|
border solid 1px #999
|
||||||
|
border-radius 2px
|
||||||
|
|
||||||
kbd
|
</style>
|
||||||
display inline
|
<script>
|
||||||
padding 0 6px
|
@tips = [
|
||||||
margin 0 2px
|
'<kbd>t</kbd>でタイムラインにフォーカスできます'
|
||||||
font-size 1em
|
'<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます'
|
||||||
font-family inherit
|
'投稿フォームにはファイルをドラッグ&ドロップできます'
|
||||||
border solid 1px #999
|
'投稿フォームにクリップボードにある画像データをペーストできます'
|
||||||
border-radius 2px
|
'ドライブにファイルをドラッグ&ドロップしてアップロードできます'
|
||||||
|
'ドライブでファイルをドラッグしてフォルダ移動できます'
|
||||||
|
'ドライブでフォルダをドラッグしてフォルダ移動できます'
|
||||||
|
'ホームをカスタマイズできます(準備中)'
|
||||||
|
'MisskeyはMIT Licenseです'
|
||||||
|
]
|
||||||
|
|
||||||
script.
|
@on \mount ~>
|
||||||
@tips = [
|
@set!
|
||||||
'<kbd>t</kbd>でタイムラインにフォーカスできます'
|
@clock = set-interval @change, 20000ms
|
||||||
'<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます'
|
|
||||||
'投稿フォームにはファイルをドラッグ&ドロップできます'
|
|
||||||
'投稿フォームにクリップボードにある画像データをペーストできます'
|
|
||||||
'ドライブにファイルをドラッグ&ドロップしてアップロードできます'
|
|
||||||
'ドライブでファイルをドラッグしてフォルダ移動できます'
|
|
||||||
'ドライブでフォルダをドラッグしてフォルダ移動できます'
|
|
||||||
'ホームをカスタマイズできます(準備中)'
|
|
||||||
'MisskeyはMIT Licenseです'
|
|
||||||
]
|
|
||||||
|
|
||||||
@on \mount ~>
|
@on \unmount ~>
|
||||||
@set!
|
clear-interval @clock
|
||||||
@clock = set-interval @change, 20000ms
|
|
||||||
|
|
||||||
@on \unmount ~>
|
@set = ~>
|
||||||
clear-interval @clock
|
@refs.text.innerHTML = @tips[Math.floor Math.random! * @tips.length]
|
||||||
|
@update!
|
||||||
|
|
||||||
@set = ~>
|
@change = ~>
|
||||||
@refs.text.innerHTML = @tips[Math.floor Math.random! * @tips.length]
|
Velocity @refs.tip, {
|
||||||
@update!
|
opacity: 0
|
||||||
|
} {
|
||||||
|
duration: 500ms
|
||||||
|
easing: \linear
|
||||||
|
complete: @set
|
||||||
|
}
|
||||||
|
|
||||||
@change = ~>
|
Velocity @refs.tip, {
|
||||||
Velocity @refs.tip, {
|
opacity: 1
|
||||||
opacity: 0
|
} {
|
||||||
} {
|
duration: 500ms
|
||||||
duration: 500ms
|
easing: \linear
|
||||||
easing: \linear
|
}
|
||||||
complete: @set
|
</script>
|
||||||
}
|
</mk-tips-home-widget>
|
||||||
|
|
||||||
Velocity @refs.tip, {
|
|
||||||
opacity: 1
|
|
||||||
} {
|
|
||||||
duration: 500ms
|
|
||||||
easing: \linear
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,154 +1,152 @@
|
||||||
mk-user-recommendation-home-widget
|
<mk-user-recommendation-home-widget>
|
||||||
p.title
|
<p class="title"><i class="fa fa-users"></i>おすすめユーザー</p>
|
||||||
i.fa.fa-users
|
<button onclick="{ refresh }" title="他を見る"><i class="fa fa-refresh"></i></button>
|
||||||
| おすすめユーザー
|
<div class="user" if="{ !loading && users.length != 0 }" each="{ _user in users }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + _user.username }"><img class="avatar" src="{ _user.avatar_url + '?thumbnail&size=42' }" alt="" data-user-preview="{ _user.id }"/></a>
|
||||||
button(onclick={ refresh }, title='他を見る'): i.fa.fa-refresh
|
<div class="body"><a class="name" href="{ CONFIG.url + '/' + _user.username }" data-user-preview="{ _user.id }">{ _user.name }</a>
|
||||||
div.user(if={ !loading && users.length != 0 }, each={ _user in users })
|
<p class="username">@{ _user.username }</p>
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + _user.username })
|
</div>
|
||||||
img.avatar(src={ _user.avatar_url + '?thumbnail&size=42' }, alt='', data-user-preview={ _user.id })
|
<mk-follow-button user="{ _user }"></mk-follow-button>
|
||||||
div.body
|
</div>
|
||||||
a.name(href={ CONFIG.url + '/' + _user.username }, data-user-preview={ _user.id }) { _user.name }
|
<p class="empty" if="{ !loading && users.length == 0 }">いません!</p>
|
||||||
p.username @{ _user.username }
|
<p class="loading" if="{ loading }"><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
|
||||||
mk-follow-button(user={ _user })
|
<mk-ellipsis></mk-ellipsis>
|
||||||
p.empty(if={ !loading && users.length == 0 })
|
</p>
|
||||||
| いません!
|
<style type="stylus">
|
||||||
p.loading(if={ loading })
|
:scope
|
||||||
i.fa.fa-spinner.fa-pulse.fa-fw
|
|
||||||
| 読み込んでいます
|
|
||||||
mk-ellipsis
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
> .title
|
|
||||||
margin 0
|
|
||||||
padding 0 16px
|
|
||||||
line-height 42px
|
|
||||||
font-size 0.9em
|
|
||||||
font-weight bold
|
|
||||||
color #888
|
|
||||||
border-bottom solid 1px #eee
|
|
||||||
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
> button
|
|
||||||
position absolute
|
|
||||||
z-index 2
|
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
padding 0
|
|
||||||
width 42px
|
|
||||||
font-size 0.9em
|
|
||||||
line-height 42px
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color #aaa
|
|
||||||
|
|
||||||
&:active
|
|
||||||
color #999
|
|
||||||
|
|
||||||
> .user
|
|
||||||
padding 16px
|
|
||||||
border-bottom solid 1px #eee
|
|
||||||
|
|
||||||
&:last-child
|
|
||||||
border-bottom none
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
display block
|
||||||
clear both
|
background #fff
|
||||||
|
|
||||||
> .avatar-anchor
|
> .title
|
||||||
display block
|
margin 0
|
||||||
float left
|
padding 0 16px
|
||||||
margin 0 12px 0 0
|
line-height 42px
|
||||||
|
font-size 0.9em
|
||||||
|
font-weight bold
|
||||||
|
color #888
|
||||||
|
border-bottom solid 1px #eee
|
||||||
|
|
||||||
> .avatar
|
> i
|
||||||
display block
|
margin-right 4px
|
||||||
|
|
||||||
|
> button
|
||||||
|
position absolute
|
||||||
|
z-index 2
|
||||||
|
top 0
|
||||||
|
right 0
|
||||||
|
padding 0
|
||||||
width 42px
|
width 42px
|
||||||
height 42px
|
font-size 0.9em
|
||||||
margin 0
|
line-height 42px
|
||||||
border-radius 8px
|
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .body
|
|
||||||
float left
|
|
||||||
width calc(100% - 54px)
|
|
||||||
|
|
||||||
> .name
|
|
||||||
margin 0
|
|
||||||
font-size 16px
|
|
||||||
line-height 24px
|
|
||||||
color #555
|
|
||||||
|
|
||||||
> .username
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
font-size 15px
|
|
||||||
line-height 16px
|
|
||||||
color #ccc
|
color #ccc
|
||||||
|
|
||||||
> mk-follow-button
|
&:hover
|
||||||
position absolute
|
color #aaa
|
||||||
top 16px
|
|
||||||
right 16px
|
|
||||||
|
|
||||||
> .empty
|
&:active
|
||||||
margin 0
|
color #999
|
||||||
padding 16px
|
|
||||||
text-align center
|
|
||||||
color #aaa
|
|
||||||
|
|
||||||
> .loading
|
> .user
|
||||||
margin 0
|
padding 16px
|
||||||
padding 16px
|
border-bottom solid 1px #eee
|
||||||
text-align center
|
|
||||||
color #aaa
|
|
||||||
|
|
||||||
> i
|
&:last-child
|
||||||
margin-right 4px
|
border-bottom none
|
||||||
|
|
||||||
script.
|
&:after
|
||||||
@mixin \api
|
content ""
|
||||||
@mixin \user-preview
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
@users = null
|
> .avatar-anchor
|
||||||
@loading = true
|
display block
|
||||||
|
float left
|
||||||
|
margin 0 12px 0 0
|
||||||
|
|
||||||
@limit = 3users
|
> .avatar
|
||||||
@page = 0
|
display block
|
||||||
|
width 42px
|
||||||
|
height 42px
|
||||||
|
margin 0
|
||||||
|
border-radius 8px
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
@on \mount ~>
|
> .body
|
||||||
@fetch!
|
float left
|
||||||
@clock = set-interval ~>
|
width calc(100% - 54px)
|
||||||
if @users.length < @limit
|
|
||||||
@fetch true
|
|
||||||
, 60000ms
|
|
||||||
|
|
||||||
@on \unmount ~>
|
> .name
|
||||||
clear-interval @clock
|
margin 0
|
||||||
|
font-size 16px
|
||||||
|
line-height 24px
|
||||||
|
color #555
|
||||||
|
|
||||||
|
> .username
|
||||||
|
display block
|
||||||
|
margin 0
|
||||||
|
font-size 15px
|
||||||
|
line-height 16px
|
||||||
|
color #ccc
|
||||||
|
|
||||||
|
> mk-follow-button
|
||||||
|
position absolute
|
||||||
|
top 16px
|
||||||
|
right 16px
|
||||||
|
|
||||||
|
> .empty
|
||||||
|
margin 0
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color #aaa
|
||||||
|
|
||||||
|
> .loading
|
||||||
|
margin 0
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color #aaa
|
||||||
|
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \user-preview
|
||||||
|
|
||||||
@fetch = (quiet = false) ~>
|
|
||||||
@loading = true
|
|
||||||
@users = null
|
@users = null
|
||||||
if not quiet then @update!
|
@loading = true
|
||||||
@api \users/recommendation do
|
|
||||||
limit: @limit
|
|
||||||
offset: @limit * @page
|
|
||||||
.then (users) ~>
|
|
||||||
@loading = false
|
|
||||||
@users = users
|
|
||||||
@update!
|
|
||||||
.catch (err, text-status) ->
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@refresh = ~>
|
@limit = 3users
|
||||||
if @users.length < @limit
|
@page = 0
|
||||||
@page = 0
|
|
||||||
else
|
@on \mount ~>
|
||||||
@page++
|
@fetch!
|
||||||
@fetch!
|
@clock = set-interval ~>
|
||||||
|
if @users.length < @limit
|
||||||
|
@fetch true
|
||||||
|
, 60000ms
|
||||||
|
|
||||||
|
@on \unmount ~>
|
||||||
|
clear-interval @clock
|
||||||
|
|
||||||
|
@fetch = (quiet = false) ~>
|
||||||
|
@loading = true
|
||||||
|
@users = null
|
||||||
|
if not quiet then @update!
|
||||||
|
@api \users/recommendation do
|
||||||
|
limit: @limit
|
||||||
|
offset: @limit * @page
|
||||||
|
.then (users) ~>
|
||||||
|
@loading = false
|
||||||
|
@users = users
|
||||||
|
@update!
|
||||||
|
.catch (err, text-status) ->
|
||||||
|
console.error err
|
||||||
|
|
||||||
|
@refresh = ~>
|
||||||
|
if @users.length < @limit
|
||||||
|
@page = 0
|
||||||
|
else
|
||||||
|
@page++
|
||||||
|
@fetch!
|
||||||
|
</script>
|
||||||
|
</mk-user-recommendation-home-widget>
|
||||||
|
|
|
@ -1,86 +1,91 @@
|
||||||
mk-home
|
<mk-home>
|
||||||
div.main
|
<div class="main">
|
||||||
div.left@left
|
<div class="left" ref="left"></div>
|
||||||
main
|
<main>
|
||||||
mk-timeline-home-widget@tl(if={ mode == 'timeline' })
|
<mk-timeline-home-widget ref="tl" if="{ mode == 'timeline' }"></mk-timeline-home-widget>
|
||||||
mk-mentions-home-widget@tl(if={ mode == 'mentions' })
|
<mk-mentions-home-widget ref="tl" if="{ mode == 'mentions' }"></mk-mentions-home-widget>
|
||||||
div.right@right
|
</main>
|
||||||
mk-detect-slow-internet-connection-notice
|
<div class="right" ref="right"></div>
|
||||||
|
</div>
|
||||||
style.
|
<mk-detect-slow-internet-connection-notice></mk-detect-slow-internet-connection-notice>
|
||||||
display block
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
> .main
|
|
||||||
margin 0 auto
|
|
||||||
max-width 1200px
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
display block
|
||||||
clear both
|
|
||||||
|
|
||||||
> *
|
> .main
|
||||||
float left
|
|
||||||
|
|
||||||
> *
|
|
||||||
display block
|
|
||||||
//border solid 1px #eaeaea
|
|
||||||
border solid 1px rgba(0, 0, 0, 0.075)
|
|
||||||
border-radius 6px
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
&:not(:last-child)
|
|
||||||
margin-bottom 16px
|
|
||||||
|
|
||||||
> main
|
|
||||||
padding 16px
|
|
||||||
width calc(100% - 275px * 2)
|
|
||||||
|
|
||||||
> *:not(main)
|
|
||||||
width 275px
|
|
||||||
|
|
||||||
> .left
|
|
||||||
padding 16px 0 16px 16px
|
|
||||||
|
|
||||||
> .right
|
|
||||||
padding 16px 16px 16px 0
|
|
||||||
|
|
||||||
@media (max-width 1100px)
|
|
||||||
> *:not(main)
|
|
||||||
display none
|
|
||||||
|
|
||||||
> main
|
|
||||||
float none
|
|
||||||
width 100%
|
|
||||||
max-width 700px
|
|
||||||
margin 0 auto
|
margin 0 auto
|
||||||
|
max-width 1200px
|
||||||
|
|
||||||
script.
|
&:after
|
||||||
@mixin \i
|
content ""
|
||||||
@mode = @opts.mode || \timeline
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
# https://github.com/riot/riot/issues/2080
|
> *
|
||||||
if @mode == '' then @mode = \timeline
|
float left
|
||||||
|
|
||||||
@home = []
|
> *
|
||||||
|
display block
|
||||||
|
//border solid 1px #eaeaea
|
||||||
|
border solid 1px rgba(0, 0, 0, 0.075)
|
||||||
|
border-radius 6px
|
||||||
|
overflow hidden
|
||||||
|
|
||||||
@on \mount ~>
|
&:not(:last-child)
|
||||||
@refs.tl.on \loaded ~>
|
margin-bottom 16px
|
||||||
@trigger \loaded
|
|
||||||
|
|
||||||
@I.data.home.for-each (widget) ~>
|
> main
|
||||||
try
|
padding 16px
|
||||||
el = document.create-element \mk- + widget.name + \-home-widget
|
width calc(100% - 275px * 2)
|
||||||
switch widget.place
|
|
||||||
| \left => @refs.left.append-child el
|
|
||||||
| \right => @refs.right.append-child el
|
|
||||||
@home.push (riot.mount el, do
|
|
||||||
id: widget.id
|
|
||||||
data: widget.data
|
|
||||||
.0)
|
|
||||||
catch e
|
|
||||||
# noop
|
|
||||||
|
|
||||||
@on \unmount ~>
|
> *:not(main)
|
||||||
@home.for-each (widget) ~>
|
width 275px
|
||||||
widget.unmount!
|
|
||||||
|
> .left
|
||||||
|
padding 16px 0 16px 16px
|
||||||
|
|
||||||
|
> .right
|
||||||
|
padding 16px 16px 16px 0
|
||||||
|
|
||||||
|
@media (max-width 1100px)
|
||||||
|
> *:not(main)
|
||||||
|
display none
|
||||||
|
|
||||||
|
> main
|
||||||
|
float none
|
||||||
|
width 100%
|
||||||
|
max-width 700px
|
||||||
|
margin 0 auto
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mode = @opts.mode || \timeline
|
||||||
|
|
||||||
|
# https://github.com/riot/riot/issues/2080
|
||||||
|
if @mode == '' then @mode = \timeline
|
||||||
|
|
||||||
|
@home = []
|
||||||
|
|
||||||
|
@on \mount ~>
|
||||||
|
@refs.tl.on \loaded ~>
|
||||||
|
@trigger \loaded
|
||||||
|
|
||||||
|
@I.data.home.for-each (widget) ~>
|
||||||
|
try
|
||||||
|
el = document.create-element \mk- + widget.name + \-home-widget
|
||||||
|
switch widget.place
|
||||||
|
| \left => @refs.left.append-child el
|
||||||
|
| \right => @refs.right.append-child el
|
||||||
|
@home.push (riot.mount el, do
|
||||||
|
id: widget.id
|
||||||
|
data: widget.data
|
||||||
|
.0)
|
||||||
|
catch e
|
||||||
|
# noop
|
||||||
|
|
||||||
|
@on \unmount ~>
|
||||||
|
@home.for-each (widget) ~>
|
||||||
|
widget.unmount!
|
||||||
|
</script>
|
||||||
|
</mk-home>
|
||||||
|
|
|
@ -1,73 +1,75 @@
|
||||||
mk-image-dialog
|
<mk-image-dialog>
|
||||||
div.bg@bg(onclick={ close })
|
<div class="bg" ref="bg" onclick="{ close }"></div><img ref="img" src="{ image.url }" alt="{ image.name }" title="{ image.name }" onclick="{ close }"/>
|
||||||
img@img(src={ image.url }, alt={ image.name }, title={ image.name }, onclick={ close })
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
position fixed
|
||||||
|
z-index 2048
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
opacity 0
|
||||||
|
|
||||||
style.
|
> .bg
|
||||||
display block
|
display block
|
||||||
position fixed
|
position fixed
|
||||||
z-index 2048
|
z-index 1
|
||||||
top 0
|
top 0
|
||||||
left 0
|
left 0
|
||||||
width 100%
|
width 100%
|
||||||
height 100%
|
height 100%
|
||||||
opacity 0
|
background rgba(0, 0, 0, 0.7)
|
||||||
|
|
||||||
> .bg
|
> img
|
||||||
display block
|
position fixed
|
||||||
position fixed
|
z-index 2
|
||||||
z-index 1
|
top 0
|
||||||
top 0
|
right 0
|
||||||
left 0
|
bottom 0
|
||||||
width 100%
|
left 0
|
||||||
height 100%
|
max-width 100%
|
||||||
background rgba(0, 0, 0, 0.7)
|
max-height 100%
|
||||||
|
margin auto
|
||||||
|
cursor zoom-out
|
||||||
|
|
||||||
> img
|
</style>
|
||||||
position fixed
|
<script>
|
||||||
z-index 2
|
@image = @opts.image
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
bottom 0
|
|
||||||
left 0
|
|
||||||
max-width 100%
|
|
||||||
max-height 100%
|
|
||||||
margin auto
|
|
||||||
cursor zoom-out
|
|
||||||
|
|
||||||
script.
|
@on \mount ~>
|
||||||
@image = @opts.image
|
Velocity @root, {
|
||||||
|
opacity: 1
|
||||||
|
} {
|
||||||
|
duration: 100ms
|
||||||
|
easing: \linear
|
||||||
|
}
|
||||||
|
|
||||||
@on \mount ~>
|
#Velocity @img, {
|
||||||
Velocity @root, {
|
# scale: 1
|
||||||
opacity: 1
|
# opacity: 1
|
||||||
} {
|
#} {
|
||||||
duration: 100ms
|
# duration: 200ms
|
||||||
easing: \linear
|
# easing: \ease-out
|
||||||
}
|
#}
|
||||||
|
|
||||||
#Velocity @img, {
|
@close = ~>
|
||||||
# scale: 1
|
Velocity @root, {
|
||||||
# opacity: 1
|
opacity: 0
|
||||||
#} {
|
} {
|
||||||
# duration: 200ms
|
duration: 100ms
|
||||||
# easing: \ease-out
|
easing: \linear
|
||||||
#}
|
complete: ~> @unmount!
|
||||||
|
}
|
||||||
|
|
||||||
@close = ~>
|
#Velocity @img, {
|
||||||
Velocity @root, {
|
# scale: 0.9
|
||||||
opacity: 0
|
# opacity: 0
|
||||||
} {
|
#} {
|
||||||
duration: 100ms
|
# duration: 200ms
|
||||||
easing: \linear
|
# easing: \ease-in
|
||||||
complete: ~> @unmount!
|
# complete: ~>
|
||||||
}
|
# @unmount!
|
||||||
|
#}
|
||||||
#Velocity @img, {
|
</script>
|
||||||
# scale: 0.9
|
</mk-image-dialog>
|
||||||
# opacity: 0
|
|
||||||
#} {
|
|
||||||
# duration: 200ms
|
|
||||||
# easing: \ease-in
|
|
||||||
# complete: ~>
|
|
||||||
# @unmount!
|
|
||||||
#}
|
|
||||||
|
|
|
@ -1,43 +1,45 @@
|
||||||
mk-images-viewer
|
<mk-images-viewer>
|
||||||
div.image@view(onmousemove={ mousemove }, style={ 'background-image: url(' + image.url + '?thumbnail' }, onclick={ click })
|
<div class="image" ref="view" onmousemove="{ mousemove }" style="{ 'background-image: url(' + image.url + '?thumbnail' }" onclick="{ click }"><img src="{ image.url + '?thumbnail&size=512' }" alt="{ image.name }" title="{ image.name }"/></div>
|
||||||
img(src={ image.url + '?thumbnail&size=512' }, alt={ image.name }, title={ image.name })
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
style.
|
|
||||||
display block
|
|
||||||
padding 8px
|
|
||||||
overflow hidden
|
|
||||||
box-shadow 0 0 4px rgba(0, 0, 0, 0.2)
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
> .image
|
|
||||||
cursor zoom-in
|
|
||||||
|
|
||||||
> img
|
|
||||||
display block
|
display block
|
||||||
max-height 256px
|
padding 8px
|
||||||
max-width 100%
|
overflow hidden
|
||||||
margin 0 auto
|
box-shadow 0 0 4px rgba(0, 0, 0, 0.2)
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
&:hover
|
> .image
|
||||||
> img
|
cursor zoom-in
|
||||||
visibility hidden
|
|
||||||
|
|
||||||
&:not(:hover)
|
> img
|
||||||
background-image none !important
|
display block
|
||||||
|
max-height 256px
|
||||||
|
max-width 100%
|
||||||
|
margin 0 auto
|
||||||
|
|
||||||
script.
|
&:hover
|
||||||
@images = @opts.images
|
> img
|
||||||
@image = @images.0
|
visibility hidden
|
||||||
|
|
||||||
@mousemove = (e) ~>
|
&:not(:hover)
|
||||||
rect = @refs.view.get-bounding-client-rect!
|
background-image none !important
|
||||||
mouse-x = e.client-x - rect.left
|
|
||||||
mouse-y = e.client-y - rect.top
|
|
||||||
xp = mouse-x / @refs.view.offset-width * 100
|
|
||||||
yp = mouse-y / @refs.view.offset-height * 100
|
|
||||||
@refs.view.style.background-position = xp + '% ' + yp + '%'
|
|
||||||
|
|
||||||
@click = ~>
|
</style>
|
||||||
dialog = document.body.append-child document.create-element \mk-image-dialog
|
<script>
|
||||||
riot.mount dialog, do
|
@images = @opts.images
|
||||||
image: @image
|
@image = @images.0
|
||||||
|
|
||||||
|
@mousemove = (e) ~>
|
||||||
|
rect = @refs.view.get-bounding-client-rect!
|
||||||
|
mouse-x = e.client-x - rect.left
|
||||||
|
mouse-y = e.client-y - rect.top
|
||||||
|
xp = mouse-x / @refs.view.offset-width * 100
|
||||||
|
yp = mouse-y / @refs.view.offset-height * 100
|
||||||
|
@refs.view.style.background-position = xp + '% ' + yp + '%'
|
||||||
|
|
||||||
|
@click = ~>
|
||||||
|
dialog = document.body.append-child document.create-element \mk-image-dialog
|
||||||
|
riot.mount dialog, do
|
||||||
|
image: @image
|
||||||
|
</script>
|
||||||
|
</mk-images-viewer>
|
||||||
|
|
|
@ -1,156 +1,157 @@
|
||||||
mk-input-dialog
|
<mk-input-dialog>
|
||||||
mk-window@window(is-modal={ true }, width={ '500px' })
|
<mk-window ref="window" is-modal="{ true }" width="{ '500px' }"><yield to="header"><i class="fa fa-i-cursor"></i>{ parent.title }</yield>
|
||||||
<yield to="header">
|
<yield to="content">
|
||||||
i.fa.fa-i-cursor
|
<div class="body">
|
||||||
| { parent.title }
|
<input ref="text" oninput="{ parent.update }" onkeydown="{ parent.onKeydown }" placeholder="{ parent.placeholder }"/>
|
||||||
</yield>
|
</div>
|
||||||
<yield to="content">
|
<div class="action">
|
||||||
div.body
|
<button class="cancel" onclick="{ parent.cancel }">キャンセル</button>
|
||||||
input@text(oninput={ parent.update }, onkeydown={ parent.on-keydown }, placeholder={ parent.placeholder })
|
<button class="ok" disabled="{ !parent.allowEmpty && refs.text.value.length == 0 }" onclick="{ parent.ok }">決定</button>
|
||||||
div.action
|
</div></yield>
|
||||||
button.cancel(onclick={ parent.cancel }) キャンセル
|
</mk-window>
|
||||||
button.ok(disabled={ !parent.allow-empty && refs.text.value.length == 0 }, onclick={ parent.ok }) 決定
|
<style type="stylus">
|
||||||
</yield>
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
> mk-window
|
||||||
display block
|
[data-yield='header']
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
> mk-window
|
[data-yield='content']
|
||||||
[data-yield='header']
|
> .body
|
||||||
> i
|
padding 16px
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
[data-yield='content']
|
> input
|
||||||
> .body
|
display block
|
||||||
padding 16px
|
padding 8px
|
||||||
|
margin 0
|
||||||
|
width 100%
|
||||||
|
max-width 100%
|
||||||
|
min-width 100%
|
||||||
|
font-size 1em
|
||||||
|
color #333
|
||||||
|
background #fff
|
||||||
|
outline none
|
||||||
|
border solid 1px rgba($theme-color, 0.1)
|
||||||
|
border-radius 4px
|
||||||
|
transition border-color .3s ease
|
||||||
|
|
||||||
> input
|
&:hover
|
||||||
display block
|
border-color rgba($theme-color, 0.2)
|
||||||
padding 8px
|
transition border-color .1s ease
|
||||||
margin 0
|
|
||||||
width 100%
|
|
||||||
max-width 100%
|
|
||||||
min-width 100%
|
|
||||||
font-size 1em
|
|
||||||
color #333
|
|
||||||
background #fff
|
|
||||||
outline none
|
|
||||||
border solid 1px rgba($theme-color, 0.1)
|
|
||||||
border-radius 4px
|
|
||||||
transition border-color .3s ease
|
|
||||||
|
|
||||||
&:hover
|
&:focus
|
||||||
border-color rgba($theme-color, 0.2)
|
color $theme-color
|
||||||
transition border-color .1s ease
|
border-color rgba($theme-color, 0.5)
|
||||||
|
transition border-color 0s ease
|
||||||
|
|
||||||
&:focus
|
&::-webkit-input-placeholder
|
||||||
color $theme-color
|
color rgba($theme-color, 0.3)
|
||||||
border-color rgba($theme-color, 0.5)
|
|
||||||
transition border-color 0s ease
|
|
||||||
|
|
||||||
&::-webkit-input-placeholder
|
> .action
|
||||||
color rgba($theme-color, 0.3)
|
height 72px
|
||||||
|
background lighten($theme-color, 95%)
|
||||||
|
|
||||||
> .action
|
.ok
|
||||||
height 72px
|
.cancel
|
||||||
background lighten($theme-color, 95%)
|
display block
|
||||||
|
|
||||||
.ok
|
|
||||||
.cancel
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
bottom 16px
|
|
||||||
cursor pointer
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
width 120px
|
|
||||||
height 40px
|
|
||||||
font-size 1em
|
|
||||||
outline none
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
position absolute
|
||||||
top -5px
|
bottom 16px
|
||||||
right -5px
|
cursor pointer
|
||||||
bottom -5px
|
padding 0
|
||||||
left -5px
|
margin 0
|
||||||
border 2px solid rgba($theme-color, 0.3)
|
width 120px
|
||||||
border-radius 8px
|
height 40px
|
||||||
|
font-size 1em
|
||||||
|
outline none
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
&:disabled
|
&:focus
|
||||||
opacity 0.7
|
&:after
|
||||||
cursor default
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
position absolute
|
||||||
|
top -5px
|
||||||
|
right -5px
|
||||||
|
bottom -5px
|
||||||
|
left -5px
|
||||||
|
border 2px solid rgba($theme-color, 0.3)
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
.ok
|
&:disabled
|
||||||
right 16px
|
opacity 0.7
|
||||||
color $theme-color-foreground
|
cursor default
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
|
||||||
border solid 1px lighten($theme-color, 15%)
|
|
||||||
|
|
||||||
&:not(:disabled)
|
.ok
|
||||||
font-weight bold
|
right 16px
|
||||||
|
color $theme-color-foreground
|
||||||
|
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
||||||
|
border solid 1px lighten($theme-color, 15%)
|
||||||
|
|
||||||
&:hover:not(:disabled)
|
&:not(:disabled)
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
font-weight bold
|
||||||
border-color $theme-color
|
|
||||||
|
|
||||||
&:active:not(:disabled)
|
&:hover:not(:disabled)
|
||||||
background $theme-color
|
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
||||||
border-color $theme-color
|
border-color $theme-color
|
||||||
|
|
||||||
.cancel
|
&:active:not(:disabled)
|
||||||
right 148px
|
background $theme-color
|
||||||
color #888
|
border-color $theme-color
|
||||||
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
|
||||||
border solid 1px #e2e2e2
|
|
||||||
|
|
||||||
&:hover
|
.cancel
|
||||||
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
right 148px
|
||||||
border-color #dcdcdc
|
color #888
|
||||||
|
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
||||||
|
border solid 1px #e2e2e2
|
||||||
|
|
||||||
&:active
|
&:hover
|
||||||
background #ececec
|
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
||||||
border-color #dcdcdc
|
border-color #dcdcdc
|
||||||
|
|
||||||
script.
|
&:active
|
||||||
@done = false
|
background #ececec
|
||||||
|
border-color #dcdcdc
|
||||||
|
|
||||||
@title = @opts.title
|
</style>
|
||||||
@placeholder = @opts.placeholder
|
<script>
|
||||||
@default = @opts.default
|
|
||||||
@allow-empty = if @opts.allow-empty? then @opts.allow-empty else true
|
|
||||||
|
|
||||||
@on \mount ~>
|
|
||||||
@text = @refs.window.refs.text
|
|
||||||
if @default?
|
|
||||||
@text.value = @default
|
|
||||||
@text.focus!
|
|
||||||
|
|
||||||
@refs.window.on \closing ~>
|
|
||||||
if @done
|
|
||||||
@opts.on-ok @text.value
|
|
||||||
else
|
|
||||||
if @opts.on-cancel?
|
|
||||||
@opts.on-cancel!
|
|
||||||
|
|
||||||
@refs.window.on \closed ~>
|
|
||||||
@unmount!
|
|
||||||
|
|
||||||
@cancel = ~>
|
|
||||||
@done = false
|
@done = false
|
||||||
@refs.window.close!
|
|
||||||
|
|
||||||
@ok = ~>
|
@title = @opts.title
|
||||||
if not @allow-empty and @text.value == '' then return
|
@placeholder = @opts.placeholder
|
||||||
@done = true
|
@default = @opts.default
|
||||||
@refs.window.close!
|
@allow-empty = if @opts.allow-empty? then @opts.allow-empty else true
|
||||||
|
|
||||||
@on-keydown = (e) ~>
|
@on \mount ~>
|
||||||
if e.which == 13 # Enter
|
@text = @refs.window.refs.text
|
||||||
e.prevent-default!
|
if @default?
|
||||||
e.stop-propagation!
|
@text.value = @default
|
||||||
@ok!
|
@text.focus!
|
||||||
|
|
||||||
|
@refs.window.on \closing ~>
|
||||||
|
if @done
|
||||||
|
@opts.on-ok @text.value
|
||||||
|
else
|
||||||
|
if @opts.on-cancel?
|
||||||
|
@opts.on-cancel!
|
||||||
|
|
||||||
|
@refs.window.on \closed ~>
|
||||||
|
@unmount!
|
||||||
|
|
||||||
|
@cancel = ~>
|
||||||
|
@done = false
|
||||||
|
@refs.window.close!
|
||||||
|
|
||||||
|
@ok = ~>
|
||||||
|
if not @allow-empty and @text.value == '' then return
|
||||||
|
@done = true
|
||||||
|
@refs.window.close!
|
||||||
|
|
||||||
|
@on-keydown = (e) ~>
|
||||||
|
if e.which == 13 # Enter
|
||||||
|
e.prevent-default!
|
||||||
|
e.stop-propagation!
|
||||||
|
@ok!
|
||||||
|
</script>
|
||||||
|
</mk-input-dialog>
|
||||||
|
|
|
@ -1,100 +1,98 @@
|
||||||
mk-list-user
|
<mk-list-user><a class="avatar-anchor" href="{ CONFIG.url + '/' + user.username }"><img class="avatar" src="{ user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/></a>
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + user.username })
|
<div class="main">
|
||||||
img.avatar(src={ user.avatar_url + '?thumbnail&size=64' }, alt='avatar')
|
<header>
|
||||||
div.main
|
<div class="left"><a class="name" href="{ CONFIG.url + '/' + user.username }">{ user.name }</a><span class="username">@{ user.username }</span></div>
|
||||||
header
|
</header>
|
||||||
div.left
|
<div class="body">
|
||||||
a.name(href={ CONFIG.url + '/' + user.username })
|
<p class="followed" if="{ user.is_followed }">フォローされています</p>
|
||||||
| { user.name }
|
<div class="bio">{ user.bio }</div>
|
||||||
span.username
|
</div>
|
||||||
| @{ user.username }
|
</div>
|
||||||
div.body
|
<mk-follow-button user="{ user }"></mk-follow-button>
|
||||||
p.followed(if={ user.is_followed }) フォローされています
|
<style type="stylus">
|
||||||
div.bio { user.bio }
|
:scope
|
||||||
mk-follow-button(user={ user })
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
font-size 16px
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
> .avatar-anchor
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
margin 0 16px 0 0
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
display block
|
||||||
width 58px
|
|
||||||
height 58px
|
|
||||||
margin 0
|
margin 0
|
||||||
border-radius 8px
|
padding 16px
|
||||||
vertical-align bottom
|
font-size 16px
|
||||||
|
|
||||||
> .main
|
|
||||||
float left
|
|
||||||
width calc(100% - 74px)
|
|
||||||
|
|
||||||
> header
|
|
||||||
margin-bottom 2px
|
|
||||||
white-space nowrap
|
|
||||||
|
|
||||||
&:after
|
&:after
|
||||||
content ""
|
content ""
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .left
|
> .avatar-anchor
|
||||||
float left
|
|
||||||
|
|
||||||
> .name
|
|
||||||
display inline
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
color #777
|
|
||||||
font-size 1em
|
|
||||||
font-weight 700
|
|
||||||
text-align left
|
|
||||||
text-decoration none
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
> .username
|
|
||||||
text-align left
|
|
||||||
margin 0 0 0 8px
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
> .body
|
|
||||||
> .followed
|
|
||||||
display inline-block
|
|
||||||
margin 0 0 4px 0
|
|
||||||
padding 2px 8px
|
|
||||||
vertical-align top
|
|
||||||
font-size 10px
|
|
||||||
color #71afc7
|
|
||||||
background #eefaff
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
> .bio
|
|
||||||
cursor default
|
|
||||||
display block
|
display block
|
||||||
margin 0
|
float left
|
||||||
padding 0
|
margin 0 16px 0 0
|
||||||
word-wrap break-word
|
|
||||||
font-size 1.1em
|
|
||||||
color #717171
|
|
||||||
|
|
||||||
> mk-follow-button
|
> .avatar
|
||||||
position absolute
|
display block
|
||||||
top 16px
|
width 58px
|
||||||
right 16px
|
height 58px
|
||||||
|
margin 0
|
||||||
|
border-radius 8px
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
script.
|
> .main
|
||||||
@user = @opts.user
|
float left
|
||||||
|
width calc(100% - 74px)
|
||||||
|
|
||||||
|
> header
|
||||||
|
margin-bottom 2px
|
||||||
|
white-space nowrap
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ""
|
||||||
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
|
> .left
|
||||||
|
float left
|
||||||
|
|
||||||
|
> .name
|
||||||
|
display inline
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
color #777
|
||||||
|
font-size 1em
|
||||||
|
font-weight 700
|
||||||
|
text-align left
|
||||||
|
text-decoration none
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
text-decoration underline
|
||||||
|
|
||||||
|
> .username
|
||||||
|
text-align left
|
||||||
|
margin 0 0 0 8px
|
||||||
|
color #ccc
|
||||||
|
|
||||||
|
> .body
|
||||||
|
> .followed
|
||||||
|
display inline-block
|
||||||
|
margin 0 0 4px 0
|
||||||
|
padding 2px 8px
|
||||||
|
vertical-align top
|
||||||
|
font-size 10px
|
||||||
|
color #71afc7
|
||||||
|
background #eefaff
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
|
> .bio
|
||||||
|
cursor default
|
||||||
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
word-wrap break-word
|
||||||
|
font-size 1.1em
|
||||||
|
color #717171
|
||||||
|
|
||||||
|
> mk-follow-button
|
||||||
|
position absolute
|
||||||
|
top 16px
|
||||||
|
right 16px
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>@user = @opts.user</script>
|
||||||
|
</mk-list-user>
|
||||||
|
|
|
@ -1,162 +1,161 @@
|
||||||
mk-messaging-form
|
<mk-messaging-form>
|
||||||
textarea@text(onkeypress={ onkeypress }, onpaste={ onpaste }, placeholder='ここにメッセージを入力')
|
<textarea ref="text" onkeypress="{ onkeypress }" onpaste="{ onpaste }" placeholder="ここにメッセージを入力"></textarea>
|
||||||
div.files
|
<div class="files"></div>
|
||||||
mk-uploader@uploader
|
<mk-uploader ref="uploader"></mk-uploader>
|
||||||
button.send(onclick={ send }, disabled={ sending }, title='メッセージを送信')
|
<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>
|
||||||
i.fa.fa-paper-plane(if={ !sending })
|
<button class="attach-from-local" type="button" title="PCから画像を添付する"><i class="fa fa-upload"></i></button>
|
||||||
i.fa.fa-spinner.fa-spin(if={ sending })
|
<button class="attach-from-drive" type="button" title="アルバムから画像を添付する"><i class="fa fa-folder-open"></i></button>
|
||||||
button.attach-from-local(type='button', title='PCから画像を添付する')
|
<input name="file" type="file" accept="image/*"/>
|
||||||
i.fa.fa-upload
|
<style type="stylus">
|
||||||
button.attach-from-drive(type='button', title='アルバムから画像を添付する')
|
:scope
|
||||||
i.fa.fa-folder-open
|
|
||||||
input(name='file', type='file', accept='image/*')
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
|
|
||||||
> textarea
|
|
||||||
cursor auto
|
|
||||||
display block
|
|
||||||
width 100%
|
|
||||||
min-width 100%
|
|
||||||
max-width 100%
|
|
||||||
height 64px
|
|
||||||
margin 0
|
|
||||||
padding 8px
|
|
||||||
font-size 1em
|
|
||||||
color #000
|
|
||||||
outline none
|
|
||||||
border none
|
|
||||||
border-top solid 1px #eee
|
|
||||||
border-radius 0
|
|
||||||
box-shadow none
|
|
||||||
background transparent
|
|
||||||
|
|
||||||
> .send
|
|
||||||
position absolute
|
|
||||||
bottom 0
|
|
||||||
right 0
|
|
||||||
margin 0
|
|
||||||
padding 10px 14px
|
|
||||||
line-height 1em
|
|
||||||
font-size 1em
|
|
||||||
color #aaa
|
|
||||||
transition color 0.1s ease
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color $theme-color
|
|
||||||
|
|
||||||
&:active
|
|
||||||
color darken($theme-color, 10%)
|
|
||||||
transition color 0s ease
|
|
||||||
|
|
||||||
.files
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0 8px
|
|
||||||
list-style none
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ''
|
|
||||||
display block
|
display block
|
||||||
clear both
|
|
||||||
|
|
||||||
> li
|
> textarea
|
||||||
display block
|
cursor auto
|
||||||
float left
|
display block
|
||||||
margin 4px
|
width 100%
|
||||||
padding 0
|
min-width 100%
|
||||||
width 64px
|
max-width 100%
|
||||||
height 64px
|
height 64px
|
||||||
background-color #eee
|
|
||||||
background-repeat no-repeat
|
|
||||||
background-position center center
|
|
||||||
background-size cover
|
|
||||||
cursor move
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
> .remove
|
|
||||||
display block
|
|
||||||
|
|
||||||
> .remove
|
|
||||||
display none
|
|
||||||
position absolute
|
|
||||||
right -6px
|
|
||||||
top -6px
|
|
||||||
margin 0
|
margin 0
|
||||||
padding 0
|
padding 8px
|
||||||
background transparent
|
font-size 1em
|
||||||
|
color #000
|
||||||
outline none
|
outline none
|
||||||
border none
|
border none
|
||||||
|
border-top solid 1px #eee
|
||||||
border-radius 0
|
border-radius 0
|
||||||
box-shadow none
|
box-shadow none
|
||||||
cursor pointer
|
background transparent
|
||||||
|
|
||||||
.attach-from-local
|
> .send
|
||||||
.attach-from-drive
|
position absolute
|
||||||
margin 0
|
bottom 0
|
||||||
padding 10px 14px
|
right 0
|
||||||
line-height 1em
|
margin 0
|
||||||
font-size 1em
|
padding 10px 14px
|
||||||
font-weight normal
|
line-height 1em
|
||||||
text-decoration none
|
font-size 1em
|
||||||
color #aaa
|
color #aaa
|
||||||
transition color 0.1s ease
|
transition color 0.1s ease
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
color $theme-color
|
color $theme-color
|
||||||
|
|
||||||
&:active
|
&:active
|
||||||
color darken($theme-color, 10%)
|
color darken($theme-color, 10%)
|
||||||
transition color 0s ease
|
transition color 0s ease
|
||||||
|
|
||||||
input[type=file]
|
.files
|
||||||
display none
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 0 8px
|
||||||
|
list-style none
|
||||||
|
|
||||||
script.
|
&:after
|
||||||
@mixin \api
|
content ''
|
||||||
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
@user = @opts.user
|
> li
|
||||||
|
display block
|
||||||
|
float left
|
||||||
|
margin 4px
|
||||||
|
padding 0
|
||||||
|
width 64px
|
||||||
|
height 64px
|
||||||
|
background-color #eee
|
||||||
|
background-repeat no-repeat
|
||||||
|
background-position center center
|
||||||
|
background-size cover
|
||||||
|
cursor move
|
||||||
|
|
||||||
@onpaste = (e) ~>
|
&:hover
|
||||||
data = e.clipboard-data
|
> .remove
|
||||||
items = data.items
|
display block
|
||||||
for i from 0 to items.length - 1
|
|
||||||
item = items[i]
|
|
||||||
switch (item.kind)
|
|
||||||
| \file =>
|
|
||||||
@upload item.get-as-file!
|
|
||||||
|
|
||||||
@onkeypress = (e) ~>
|
> .remove
|
||||||
if (e.which == 10 || e.which == 13) && e.ctrl-key
|
display none
|
||||||
@send!
|
position absolute
|
||||||
|
right -6px
|
||||||
|
top -6px
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
background transparent
|
||||||
|
outline none
|
||||||
|
border none
|
||||||
|
border-radius 0
|
||||||
|
box-shadow none
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
@select-file = ~>
|
.attach-from-local
|
||||||
@refs.file.click!
|
.attach-from-drive
|
||||||
|
margin 0
|
||||||
|
padding 10px 14px
|
||||||
|
line-height 1em
|
||||||
|
font-size 1em
|
||||||
|
font-weight normal
|
||||||
|
text-decoration none
|
||||||
|
color #aaa
|
||||||
|
transition color 0.1s ease
|
||||||
|
|
||||||
@select-file-from-drive = ~>
|
&:hover
|
||||||
browser = document.body.append-child document.create-element \mk-select-file-from-drive-window
|
color $theme-color
|
||||||
event = riot.observable!
|
|
||||||
riot.mount browser, do
|
|
||||||
multiple: true
|
|
||||||
event: event
|
|
||||||
event.one \selected (files) ~>
|
|
||||||
files.for-each @add-file
|
|
||||||
|
|
||||||
@send = ~>
|
&:active
|
||||||
@sending = true
|
color darken($theme-color, 10%)
|
||||||
@api \messaging/messages/create do
|
transition color 0s ease
|
||||||
user_id: @user.id
|
|
||||||
text: @refs.text.value
|
input[type=file]
|
||||||
.then (message) ~>
|
display none
|
||||||
@clear!
|
|
||||||
.catch (err) ~>
|
</style>
|
||||||
console.error err
|
<script>
|
||||||
.then ~>
|
@mixin \api
|
||||||
@sending = false
|
|
||||||
|
@user = @opts.user
|
||||||
|
|
||||||
|
@onpaste = (e) ~>
|
||||||
|
data = e.clipboard-data
|
||||||
|
items = data.items
|
||||||
|
for i from 0 to items.length - 1
|
||||||
|
item = items[i]
|
||||||
|
switch (item.kind)
|
||||||
|
| \file =>
|
||||||
|
@upload item.get-as-file!
|
||||||
|
|
||||||
|
@onkeypress = (e) ~>
|
||||||
|
if (e.which == 10 || e.which == 13) && e.ctrl-key
|
||||||
|
@send!
|
||||||
|
|
||||||
|
@select-file = ~>
|
||||||
|
@refs.file.click!
|
||||||
|
|
||||||
|
@select-file-from-drive = ~>
|
||||||
|
browser = document.body.append-child document.create-element \mk-select-file-from-drive-window
|
||||||
|
event = riot.observable!
|
||||||
|
riot.mount browser, do
|
||||||
|
multiple: true
|
||||||
|
event: event
|
||||||
|
event.one \selected (files) ~>
|
||||||
|
files.for-each @add-file
|
||||||
|
|
||||||
|
@send = ~>
|
||||||
|
@sending = true
|
||||||
|
@api \messaging/messages/create do
|
||||||
|
user_id: @user.id
|
||||||
|
text: @refs.text.value
|
||||||
|
.then (message) ~>
|
||||||
|
@clear!
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
.then ~>
|
||||||
|
@sending = false
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@clear = ~>
|
||||||
|
@refs.text.value = ''
|
||||||
|
@files = []
|
||||||
@update!
|
@update!
|
||||||
|
</script>
|
||||||
@clear = ~>
|
</mk-messaging-form>
|
||||||
@refs.text.value = ''
|
|
||||||
@files = []
|
|
||||||
@update!
|
|
||||||
|
|
|
@ -1,302 +1,301 @@
|
||||||
mk-messaging
|
<mk-messaging>
|
||||||
div.search
|
<div class="search">
|
||||||
div.form
|
<div class="form">
|
||||||
label(for='search-input')
|
<label for="search-input"><i class="fa fa-search"></i></label>
|
||||||
i.fa.fa-search
|
<input ref="searchInput" type="search" oninput="{ search }" placeholder="ユーザーを探す"/>
|
||||||
input@search-input(type='search', oninput={ search }, placeholder='ユーザーを探す')
|
</div>
|
||||||
div.result
|
<div class="result">
|
||||||
ol.users(if={ search-result.length > 0 })
|
<ol class="users" if="{ searchResult.length > 0 }">
|
||||||
li(each={ user in search-result })
|
<li each="{ user in searchResult }"><a onclick="{ user._click }"><img class="avatar" src="{ user.avatar_url + '?thumbnail&size=32' }" alt=""/><span class="name">{ user.name }</span><span class="username">@{ user.username }</span></a></li>
|
||||||
a(onclick={ user._click })
|
</ol>
|
||||||
img.avatar(src={ user.avatar_url + '?thumbnail&size=32' }, alt='')
|
</div>
|
||||||
span.name { user.name }
|
</div>
|
||||||
span.username @{ user.username }
|
<div class="main">
|
||||||
div.main
|
<div class="history" if="{ history.length > 0 }">
|
||||||
div.history(if={ history.length > 0 })
|
<virtual each="{ history }"><a class="user" data-is-me="{ is_me }" data-is-read="{ is_read }" onclick="{ _click }">
|
||||||
virtual(each={ history })
|
<div><img class="avatar" src="{ (is_me ? recipient.avatar_url : user.avatar_url) + '?thumbnail&size=64' }" alt=""/>
|
||||||
a.user(data-is-me={ is_me }, data-is-read={ is_read }, onclick={ _click }): div
|
<header><span class="name">{ is_me ? recipient.name : user.name }</span><span class="username">{ '@' + (is_me ? recipient.username : user.username ) }</span>
|
||||||
img.avatar(src={ (is_me ? recipient.avatar_url : user.avatar_url) + '?thumbnail&size=64' }, alt='')
|
<mk-time time="{ created_at }"></mk-time>
|
||||||
header
|
</header>
|
||||||
span.name { is_me ? recipient.name : user.name }
|
<div class="body">
|
||||||
span.username { '@' + (is_me ? recipient.username : user.username ) }
|
<p class="text"><span class="me" if="{ is_me }">あなた:</span>{ text }</p>
|
||||||
mk-time(time={ created_at })
|
</div>
|
||||||
div.body
|
</div></a></virtual>
|
||||||
p.text
|
</div>
|
||||||
span.me(if={ is_me }) あなた:
|
<p class="no-history" if="{ history.length == 0 }">履歴はありません。<br/>ユーザーを検索して、いつでもメッセージを送受信できます。</p>
|
||||||
| { text }
|
</div>
|
||||||
p.no-history(if={ history.length == 0 })
|
<style type="stylus">
|
||||||
| 履歴はありません。
|
:scope
|
||||||
br
|
display block
|
||||||
| ユーザーを検索して、いつでもメッセージを送受信できます。
|
|
||||||
|
|
||||||
style.
|
> .search
|
||||||
display block
|
|
||||||
|
|
||||||
> .search
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
z-index 1
|
|
||||||
width 100%
|
|
||||||
background #fff
|
|
||||||
box-shadow 0 0px 2px rgba(0, 0, 0, 0.2)
|
|
||||||
|
|
||||||
> .form
|
|
||||||
padding 8px
|
|
||||||
background #f7f7f7
|
|
||||||
|
|
||||||
> label
|
|
||||||
display block
|
display block
|
||||||
position absolute
|
position absolute
|
||||||
top 0
|
top 0
|
||||||
left 8px
|
left 0
|
||||||
z-index 1
|
z-index 1
|
||||||
height 100%
|
|
||||||
width 38px
|
|
||||||
pointer-events none
|
|
||||||
|
|
||||||
> i
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
bottom 0
|
|
||||||
left 0
|
|
||||||
width 1em
|
|
||||||
height 1em
|
|
||||||
margin auto
|
|
||||||
color #555
|
|
||||||
|
|
||||||
> input
|
|
||||||
margin 0
|
|
||||||
padding 0 12px 0 38px
|
|
||||||
width 100%
|
width 100%
|
||||||
font-size 1em
|
|
||||||
line-height 38px
|
|
||||||
color #000
|
|
||||||
outline none
|
|
||||||
border solid 1px #eee
|
|
||||||
border-radius 5px
|
|
||||||
box-shadow none
|
|
||||||
transition color 0.5s ease, border 0.5s ease
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
border solid 1px #ddd
|
|
||||||
transition border 0.2s ease
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
color darken($theme-color, 20%)
|
|
||||||
border solid 1px $theme-color
|
|
||||||
transition color 0, border 0
|
|
||||||
|
|
||||||
> .result
|
|
||||||
display block
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
z-index 2
|
|
||||||
width 100%
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
> .users
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
list-style none
|
|
||||||
|
|
||||||
> li
|
|
||||||
> a
|
|
||||||
display inline-block
|
|
||||||
z-index 1
|
|
||||||
width 100%
|
|
||||||
padding 8px 32px
|
|
||||||
vertical-align top
|
|
||||||
white-space nowrap
|
|
||||||
overflow hidden
|
|
||||||
color rgba(0, 0, 0, 0.8)
|
|
||||||
text-decoration none
|
|
||||||
transition none
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color #fff
|
|
||||||
background $theme-color
|
|
||||||
|
|
||||||
.name
|
|
||||||
color #fff
|
|
||||||
|
|
||||||
.username
|
|
||||||
color #fff
|
|
||||||
|
|
||||||
&:active
|
|
||||||
color #fff
|
|
||||||
background darken($theme-color, 10%)
|
|
||||||
|
|
||||||
.name
|
|
||||||
color #fff
|
|
||||||
|
|
||||||
.username
|
|
||||||
color #fff
|
|
||||||
|
|
||||||
.avatar
|
|
||||||
vertical-align middle
|
|
||||||
min-width 32px
|
|
||||||
min-height 32px
|
|
||||||
max-width 32px
|
|
||||||
max-height 32px
|
|
||||||
margin 0 8px 0 0
|
|
||||||
border-radius 6px
|
|
||||||
|
|
||||||
.name
|
|
||||||
margin 0 8px 0 0
|
|
||||||
/*font-weight bold*/
|
|
||||||
font-weight normal
|
|
||||||
color rgba(0, 0, 0, 0.8)
|
|
||||||
|
|
||||||
.username
|
|
||||||
font-weight normal
|
|
||||||
color rgba(0, 0, 0, 0.3)
|
|
||||||
|
|
||||||
> .main
|
|
||||||
padding-top 56px
|
|
||||||
|
|
||||||
> .history
|
|
||||||
|
|
||||||
> a
|
|
||||||
display block
|
|
||||||
padding 20px 30px
|
|
||||||
text-decoration none
|
|
||||||
background #fff
|
background #fff
|
||||||
border-bottom solid 1px #eee
|
box-shadow 0 0px 2px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
*
|
> .form
|
||||||
pointer-events none
|
padding 8px
|
||||||
user-select none
|
background #f7f7f7
|
||||||
|
|
||||||
&:hover
|
> label
|
||||||
background #fafafa
|
display block
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 8px
|
||||||
|
z-index 1
|
||||||
|
height 100%
|
||||||
|
width 38px
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
> .avatar
|
> i
|
||||||
filter saturate(200%)
|
display block
|
||||||
|
|
||||||
&:active
|
|
||||||
background #eee
|
|
||||||
|
|
||||||
&[data-is-read]
|
|
||||||
&[data-is-me]
|
|
||||||
opacity 0.8
|
|
||||||
|
|
||||||
&:not([data-is-me]):not([data-is-read])
|
|
||||||
background-image url("/_/resources/desktop/unread.svg")
|
|
||||||
background-repeat no-repeat
|
|
||||||
background-position 0 center
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
> div
|
|
||||||
max-width 500px
|
|
||||||
margin 0 auto
|
|
||||||
|
|
||||||
> header
|
|
||||||
margin-bottom 2px
|
|
||||||
white-space nowrap
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
> .name
|
|
||||||
text-align left
|
|
||||||
display inline
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
font-size 1em
|
|
||||||
color rgba(0, 0, 0, 0.9)
|
|
||||||
font-weight bold
|
|
||||||
transition all 0.1s ease
|
|
||||||
|
|
||||||
> .username
|
|
||||||
text-align left
|
|
||||||
margin 0 0 0 8px
|
|
||||||
color rgba(0, 0, 0, 0.5)
|
|
||||||
|
|
||||||
> mk-time
|
|
||||||
position absolute
|
position absolute
|
||||||
top 0
|
top 0
|
||||||
right 0
|
right 0
|
||||||
display inline
|
bottom 0
|
||||||
color rgba(0, 0, 0, 0.5)
|
left 0
|
||||||
font-size small
|
width 1em
|
||||||
|
height 1em
|
||||||
|
margin auto
|
||||||
|
color #555
|
||||||
|
|
||||||
> .avatar
|
> input
|
||||||
float left
|
margin 0
|
||||||
width 54px
|
padding 0 12px 0 38px
|
||||||
height 54px
|
width 100%
|
||||||
margin 0 16px 0 0
|
font-size 1em
|
||||||
border-radius 8px
|
line-height 38px
|
||||||
transition all 0.1s ease
|
color #000
|
||||||
|
outline none
|
||||||
|
border solid 1px #eee
|
||||||
|
border-radius 5px
|
||||||
|
box-shadow none
|
||||||
|
transition color 0.5s ease, border 0.5s ease
|
||||||
|
|
||||||
> .body
|
&:hover
|
||||||
|
border solid 1px #ddd
|
||||||
|
transition border 0.2s ease
|
||||||
|
|
||||||
> .text
|
&:focus
|
||||||
|
color darken($theme-color, 20%)
|
||||||
|
border solid 1px $theme-color
|
||||||
|
transition color 0, border 0
|
||||||
|
|
||||||
|
> .result
|
||||||
|
display block
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
z-index 2
|
||||||
|
width 100%
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
background #fff
|
||||||
|
|
||||||
|
> .users
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
list-style none
|
||||||
|
|
||||||
|
> li
|
||||||
|
> a
|
||||||
|
display inline-block
|
||||||
|
z-index 1
|
||||||
|
width 100%
|
||||||
|
padding 8px 32px
|
||||||
|
vertical-align top
|
||||||
|
white-space nowrap
|
||||||
|
overflow hidden
|
||||||
|
color rgba(0, 0, 0, 0.8)
|
||||||
|
text-decoration none
|
||||||
|
transition none
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
color #fff
|
||||||
|
background $theme-color
|
||||||
|
|
||||||
|
.name
|
||||||
|
color #fff
|
||||||
|
|
||||||
|
.username
|
||||||
|
color #fff
|
||||||
|
|
||||||
|
&:active
|
||||||
|
color #fff
|
||||||
|
background darken($theme-color, 10%)
|
||||||
|
|
||||||
|
.name
|
||||||
|
color #fff
|
||||||
|
|
||||||
|
.username
|
||||||
|
color #fff
|
||||||
|
|
||||||
|
.avatar
|
||||||
|
vertical-align middle
|
||||||
|
min-width 32px
|
||||||
|
min-height 32px
|
||||||
|
max-width 32px
|
||||||
|
max-height 32px
|
||||||
|
margin 0 8px 0 0
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
.name
|
||||||
|
margin 0 8px 0 0
|
||||||
|
/*font-weight bold*/
|
||||||
|
font-weight normal
|
||||||
|
color rgba(0, 0, 0, 0.8)
|
||||||
|
|
||||||
|
.username
|
||||||
|
font-weight normal
|
||||||
|
color rgba(0, 0, 0, 0.3)
|
||||||
|
|
||||||
|
> .main
|
||||||
|
padding-top 56px
|
||||||
|
|
||||||
|
> .history
|
||||||
|
|
||||||
|
> a
|
||||||
|
display block
|
||||||
|
padding 20px 30px
|
||||||
|
text-decoration none
|
||||||
|
background #fff
|
||||||
|
border-bottom solid 1px #eee
|
||||||
|
|
||||||
|
*
|
||||||
|
pointer-events none
|
||||||
|
user-select none
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background #fafafa
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
filter saturate(200%)
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background #eee
|
||||||
|
|
||||||
|
&[data-is-read]
|
||||||
|
&[data-is-me]
|
||||||
|
opacity 0.8
|
||||||
|
|
||||||
|
&:not([data-is-me]):not([data-is-read])
|
||||||
|
background-image url("/_/resources/desktop/unread.svg")
|
||||||
|
background-repeat no-repeat
|
||||||
|
background-position 0 center
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ""
|
||||||
display block
|
display block
|
||||||
margin 0 0 0 0
|
clear both
|
||||||
padding 0
|
|
||||||
overflow hidden
|
|
||||||
word-wrap break-word
|
|
||||||
font-size 1.1em
|
|
||||||
color rgba(0, 0, 0, 0.8)
|
|
||||||
|
|
||||||
.me
|
> div
|
||||||
color rgba(0, 0, 0, 0.4)
|
max-width 500px
|
||||||
|
margin 0 auto
|
||||||
|
|
||||||
> .image
|
> header
|
||||||
display block
|
margin-bottom 2px
|
||||||
max-width 100%
|
white-space nowrap
|
||||||
max-height 512px
|
overflow hidden
|
||||||
|
|
||||||
> .no-history
|
> .name
|
||||||
margin 0
|
text-align left
|
||||||
padding 2em 1em
|
display inline
|
||||||
text-align center
|
margin 0
|
||||||
color #999
|
padding 0
|
||||||
font-weight 500
|
font-size 1em
|
||||||
|
color rgba(0, 0, 0, 0.9)
|
||||||
|
font-weight bold
|
||||||
|
transition all 0.1s ease
|
||||||
|
|
||||||
script.
|
> .username
|
||||||
@mixin \i
|
text-align left
|
||||||
@mixin \api
|
margin 0 0 0 8px
|
||||||
|
color rgba(0, 0, 0, 0.5)
|
||||||
|
|
||||||
@search-result = []
|
> mk-time
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
right 0
|
||||||
|
display inline
|
||||||
|
color rgba(0, 0, 0, 0.5)
|
||||||
|
font-size small
|
||||||
|
|
||||||
@on \mount ~>
|
> .avatar
|
||||||
@api \messaging/history
|
float left
|
||||||
.then (history) ~>
|
width 54px
|
||||||
@is-loading = false
|
height 54px
|
||||||
history.for-each (message) ~>
|
margin 0 16px 0 0
|
||||||
message.is_me = message.user_id == @I.id
|
border-radius 8px
|
||||||
message._click = ~>
|
transition all 0.1s ease
|
||||||
if message.is_me
|
|
||||||
@trigger \navigate-user message.recipient
|
|
||||||
else
|
|
||||||
@trigger \navigate-user message.user
|
|
||||||
@history = history
|
|
||||||
@update!
|
|
||||||
.catch (err) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@search = ~>
|
> .body
|
||||||
q = @refs.search-input.value
|
|
||||||
if q == ''
|
> .text
|
||||||
@search-result = []
|
display block
|
||||||
else
|
margin 0 0 0 0
|
||||||
@api \users/search do
|
padding 0
|
||||||
query: q
|
overflow hidden
|
||||||
.then (users) ~>
|
word-wrap break-word
|
||||||
users.for-each (user) ~>
|
font-size 1.1em
|
||||||
user._click = ~>
|
color rgba(0, 0, 0, 0.8)
|
||||||
@trigger \navigate-user user
|
|
||||||
@search-result = []
|
.me
|
||||||
@search-result = users
|
color rgba(0, 0, 0, 0.4)
|
||||||
|
|
||||||
|
> .image
|
||||||
|
display block
|
||||||
|
max-width 100%
|
||||||
|
max-height 512px
|
||||||
|
|
||||||
|
> .no-history
|
||||||
|
margin 0
|
||||||
|
padding 2em 1em
|
||||||
|
text-align center
|
||||||
|
color #999
|
||||||
|
font-weight 500
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mixin \api
|
||||||
|
|
||||||
|
@search-result = []
|
||||||
|
|
||||||
|
@on \mount ~>
|
||||||
|
@api \messaging/history
|
||||||
|
.then (history) ~>
|
||||||
|
@is-loading = false
|
||||||
|
history.for-each (message) ~>
|
||||||
|
message.is_me = message.user_id == @I.id
|
||||||
|
message._click = ~>
|
||||||
|
if message.is_me
|
||||||
|
@trigger \navigate-user message.recipient
|
||||||
|
else
|
||||||
|
@trigger \navigate-user message.user
|
||||||
|
@history = history
|
||||||
@update!
|
@update!
|
||||||
.catch (err) ~>
|
.catch (err) ~>
|
||||||
console.error err
|
console.error err
|
||||||
|
|
||||||
|
@search = ~>
|
||||||
|
q = @refs.search-input.value
|
||||||
|
if q == ''
|
||||||
|
@search-result = []
|
||||||
|
else
|
||||||
|
@api \users/search do
|
||||||
|
query: q
|
||||||
|
.then (users) ~>
|
||||||
|
users.for-each (user) ~>
|
||||||
|
user._click = ~>
|
||||||
|
@trigger \navigate-user user
|
||||||
|
@search-result = []
|
||||||
|
@search-result = users
|
||||||
|
@update!
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
</script>
|
||||||
|
</mk-messaging>
|
||||||
|
|
|
@ -1,227 +1,230 @@
|
||||||
mk-messaging-message(data-is-me={ message.is_me })
|
<mk-messaging-message data-is-me="{ message.is_me }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + message.user.username }" title="{ message.user.username }" target="_blank"><img class="avatar" src="{ message.user.avatar_url + '?thumbnail&size=64' }" alt=""/></a>
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + message.user.username }, title={ message.user.username }, target='_blank')
|
<div class="content-container">
|
||||||
img.avatar(src={ message.user.avatar_url + '?thumbnail&size=64' }, alt='')
|
<div class="balloon">
|
||||||
div.content-container
|
<p class="read" if="{ message.is_me && message.is_read }">既読</p>
|
||||||
div.balloon
|
<button class="delete-button" if="{ message.is_me }" title="メッセージを削除"><img src="/_/resources/desktop/messaging/delete.png" alt="Delete"/></button>
|
||||||
p.read(if={ message.is_me && message.is_read }) 既読
|
<div class="content" if="{ !message.is_deleted }">
|
||||||
button.delete-button(if={ message.is_me }, title='メッセージを削除')
|
<div ref="text"></div>
|
||||||
img(src='/_/resources/desktop/messaging/delete.png', alt='Delete')
|
<div class="image" if="{ message.file }"><img src="{ message.file.url }" alt="image" title="{ message.file.name }"/></div>
|
||||||
div.content(if={ !message.is_deleted })
|
</div>
|
||||||
div@text
|
<div class="content" if="{ message.is_deleted }">
|
||||||
div.image(if={ message.file })
|
<p class="is-deleted">このメッセージは削除されました</p>
|
||||||
img(src={ message.file.url }, alt='image', title={ message.file.name })
|
</div>
|
||||||
div.content(if={ message.is_deleted })
|
</div>
|
||||||
p.is-deleted このメッセージは削除されました
|
<footer>
|
||||||
footer
|
<mk-time time="{ message.created_at }"></mk-time><i class="fa fa-pencil is-edited" if="{ message.is_edited }"></i>
|
||||||
mk-time(time={ message.created_at })
|
</footer>
|
||||||
i.fa.fa-pencil.is-edited(if={ message.is_edited })
|
</div>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
$me-balloon-color = #23A7B6
|
||||||
|
|
||||||
style.
|
|
||||||
$me-balloon-color = #23A7B6
|
|
||||||
|
|
||||||
display block
|
|
||||||
padding 10px 12px 10px 12px
|
|
||||||
background-color transparent
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
> .avatar-anchor
|
|
||||||
display block
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
display block
|
||||||
min-width 54px
|
padding 10px 12px 10px 12px
|
||||||
min-height 54px
|
background-color transparent
|
||||||
max-width 54px
|
|
||||||
max-height 54px
|
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
|
||||||
transition all 0.1s ease
|
|
||||||
|
|
||||||
> .content-container
|
&:after
|
||||||
display block
|
|
||||||
margin 0 12px
|
|
||||||
padding 0
|
|
||||||
max-width calc(100% - 78px)
|
|
||||||
|
|
||||||
> .balloon
|
|
||||||
display block
|
|
||||||
float inherit
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
max-width 100%
|
|
||||||
min-height 38px
|
|
||||||
border-radius 16px
|
|
||||||
|
|
||||||
&:before
|
|
||||||
content ""
|
content ""
|
||||||
pointer-events none
|
|
||||||
display block
|
display block
|
||||||
position absolute
|
clear both
|
||||||
top 12px
|
|
||||||
|
|
||||||
&:hover
|
> .avatar-anchor
|
||||||
> .delete-button
|
display block
|
||||||
|
|
||||||
|
> .avatar
|
||||||
display block
|
display block
|
||||||
|
min-width 54px
|
||||||
|
min-height 54px
|
||||||
|
max-width 54px
|
||||||
|
max-height 54px
|
||||||
|
margin 0
|
||||||
|
border-radius 8px
|
||||||
|
transition all 0.1s ease
|
||||||
|
|
||||||
> .delete-button
|
> .content-container
|
||||||
display none
|
display block
|
||||||
position absolute
|
margin 0 12px
|
||||||
z-index 1
|
|
||||||
top -4px
|
|
||||||
right -4px
|
|
||||||
margin 0
|
|
||||||
padding 0
|
padding 0
|
||||||
cursor pointer
|
max-width calc(100% - 78px)
|
||||||
outline none
|
|
||||||
border none
|
|
||||||
border-radius 0
|
|
||||||
box-shadow none
|
|
||||||
background transparent
|
|
||||||
|
|
||||||
> img
|
> .balloon
|
||||||
vertical-align bottom
|
|
||||||
width 16px
|
|
||||||
height 16px
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
> .read
|
|
||||||
user-select none
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
z-index 1
|
|
||||||
bottom -4px
|
|
||||||
left -12px
|
|
||||||
margin 0
|
|
||||||
color rgba(0, 0, 0, 0.5)
|
|
||||||
font-size 11px
|
|
||||||
|
|
||||||
> .content
|
|
||||||
|
|
||||||
> .is-deleted
|
|
||||||
display block
|
display block
|
||||||
|
float inherit
|
||||||
margin 0
|
margin 0
|
||||||
padding 0
|
padding 0
|
||||||
overflow hidden
|
max-width 100%
|
||||||
word-wrap break-word
|
min-height 38px
|
||||||
font-size 1em
|
border-radius 16px
|
||||||
color rgba(0, 0, 0, 0.5)
|
|
||||||
|
|
||||||
> [ref='text']
|
&:before
|
||||||
display block
|
content ""
|
||||||
margin 0
|
pointer-events none
|
||||||
padding 8px 16px
|
display block
|
||||||
overflow hidden
|
position absolute
|
||||||
word-wrap break-word
|
top 12px
|
||||||
font-size 1em
|
|
||||||
color rgba(0, 0, 0, 0.8)
|
|
||||||
|
|
||||||
&, *
|
&:hover
|
||||||
user-select text
|
> .delete-button
|
||||||
cursor auto
|
|
||||||
|
|
||||||
& + .file
|
|
||||||
&.image
|
|
||||||
> img
|
|
||||||
border-radius 0 0 16px 16px
|
|
||||||
|
|
||||||
> .file
|
|
||||||
&.image
|
|
||||||
> img
|
|
||||||
display block
|
display block
|
||||||
max-width 100%
|
|
||||||
max-height 512px
|
|
||||||
border-radius 16px
|
|
||||||
|
|
||||||
> footer
|
> .delete-button
|
||||||
display block
|
display none
|
||||||
clear both
|
position absolute
|
||||||
margin 0
|
z-index 1
|
||||||
padding 2px
|
top -4px
|
||||||
font-size 10px
|
right -4px
|
||||||
color rgba(0, 0, 0, 0.4)
|
margin 0
|
||||||
|
padding 0
|
||||||
|
cursor pointer
|
||||||
|
outline none
|
||||||
|
border none
|
||||||
|
border-radius 0
|
||||||
|
box-shadow none
|
||||||
|
background transparent
|
||||||
|
|
||||||
> .is-edited
|
> img
|
||||||
margin-left 4px
|
vertical-align bottom
|
||||||
|
width 16px
|
||||||
|
height 16px
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
&:not([data-is-me='true'])
|
> .read
|
||||||
> .avatar-anchor
|
user-select none
|
||||||
float left
|
display block
|
||||||
|
position absolute
|
||||||
|
z-index 1
|
||||||
|
bottom -4px
|
||||||
|
left -12px
|
||||||
|
margin 0
|
||||||
|
color rgba(0, 0, 0, 0.5)
|
||||||
|
font-size 11px
|
||||||
|
|
||||||
> .content-container
|
> .content
|
||||||
float left
|
|
||||||
|
|
||||||
> .balloon
|
> .is-deleted
|
||||||
background #eee
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
overflow hidden
|
||||||
|
word-wrap break-word
|
||||||
|
font-size 1em
|
||||||
|
color rgba(0, 0, 0, 0.5)
|
||||||
|
|
||||||
&:before
|
> [ref='text']
|
||||||
left -14px
|
display block
|
||||||
border-top solid 8px transparent
|
margin 0
|
||||||
border-right solid 8px #eee
|
padding 8px 16px
|
||||||
border-bottom solid 8px transparent
|
overflow hidden
|
||||||
border-left solid 8px transparent
|
word-wrap break-word
|
||||||
|
font-size 1em
|
||||||
|
color rgba(0, 0, 0, 0.8)
|
||||||
|
|
||||||
> footer
|
&, *
|
||||||
text-align left
|
user-select text
|
||||||
|
cursor auto
|
||||||
|
|
||||||
&[data-is-me='true']
|
& + .file
|
||||||
> .avatar-anchor
|
&.image
|
||||||
float right
|
> img
|
||||||
|
border-radius 0 0 16px 16px
|
||||||
|
|
||||||
> .content-container
|
> .file
|
||||||
float right
|
&.image
|
||||||
|
> img
|
||||||
|
display block
|
||||||
|
max-width 100%
|
||||||
|
max-height 512px
|
||||||
|
border-radius 16px
|
||||||
|
|
||||||
> .balloon
|
> footer
|
||||||
background $me-balloon-color
|
display block
|
||||||
|
clear both
|
||||||
|
margin 0
|
||||||
|
padding 2px
|
||||||
|
font-size 10px
|
||||||
|
color rgba(0, 0, 0, 0.4)
|
||||||
|
|
||||||
&:before
|
> .is-edited
|
||||||
right -14px
|
margin-left 4px
|
||||||
left auto
|
|
||||||
border-top solid 8px transparent
|
|
||||||
border-right solid 8px transparent
|
|
||||||
border-bottom solid 8px transparent
|
|
||||||
border-left solid 8px $me-balloon-color
|
|
||||||
|
|
||||||
> .content
|
&:not([data-is-me='true'])
|
||||||
|
> .avatar-anchor
|
||||||
|
float left
|
||||||
|
|
||||||
> p.is-deleted
|
> .content-container
|
||||||
color rgba(255, 255, 255, 0.5)
|
float left
|
||||||
|
|
||||||
> [ref='text']
|
> .balloon
|
||||||
&, *
|
background #eee
|
||||||
color #fff !important
|
|
||||||
|
|
||||||
> footer
|
&:before
|
||||||
text-align right
|
left -14px
|
||||||
|
border-top solid 8px transparent
|
||||||
|
border-right solid 8px #eee
|
||||||
|
border-bottom solid 8px transparent
|
||||||
|
border-left solid 8px transparent
|
||||||
|
|
||||||
&[data-is-deleted='true']
|
> footer
|
||||||
> .content-container
|
text-align left
|
||||||
opacity 0.5
|
|
||||||
|
|
||||||
script.
|
&[data-is-me='true']
|
||||||
@mixin \i
|
> .avatar-anchor
|
||||||
@mixin \text
|
float right
|
||||||
|
|
||||||
@message = @opts.message
|
> .content-container
|
||||||
@message.is_me = @message.user.id == @I.id
|
float right
|
||||||
|
|
||||||
@on \mount ~>
|
> .balloon
|
||||||
if @message.text?
|
background $me-balloon-color
|
||||||
tokens = @analyze @message.text
|
|
||||||
|
|
||||||
@refs.text.innerHTML = @compile tokens
|
&:before
|
||||||
|
right -14px
|
||||||
|
left auto
|
||||||
|
border-top solid 8px transparent
|
||||||
|
border-right solid 8px transparent
|
||||||
|
border-bottom solid 8px transparent
|
||||||
|
border-left solid 8px $me-balloon-color
|
||||||
|
|
||||||
@refs.text.children.for-each (e) ~>
|
> .content
|
||||||
if e.tag-name == \MK-URL
|
|
||||||
riot.mount e
|
|
||||||
|
|
||||||
# URLをプレビュー
|
> p.is-deleted
|
||||||
tokens
|
color rgba(255, 255, 255, 0.5)
|
||||||
.filter (t) -> t.type == \link
|
|
||||||
.map (t) ~>
|
> [ref='text']
|
||||||
@preview = @refs.text.append-child document.create-element \mk-url-preview
|
&, *
|
||||||
riot.mount @preview, do
|
color #fff !important
|
||||||
url: t.content
|
|
||||||
|
> footer
|
||||||
|
text-align right
|
||||||
|
|
||||||
|
&[data-is-deleted='true']
|
||||||
|
> .content-container
|
||||||
|
opacity 0.5
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mixin \text
|
||||||
|
|
||||||
|
@message = @opts.message
|
||||||
|
@message.is_me = @message.user.id == @I.id
|
||||||
|
|
||||||
|
@on \mount ~>
|
||||||
|
if @message.text?
|
||||||
|
tokens = @analyze @message.text
|
||||||
|
|
||||||
|
@refs.text.innerHTML = @compile tokens
|
||||||
|
|
||||||
|
@refs.text.children.for-each (e) ~>
|
||||||
|
if e.tag-name == \MK-URL
|
||||||
|
riot.mount e
|
||||||
|
|
||||||
|
# URLをプレビュー
|
||||||
|
tokens
|
||||||
|
.filter (t) -> t.type == \link
|
||||||
|
.map (t) ~>
|
||||||
|
@preview = @refs.text.append-child document.create-element \mk-url-preview
|
||||||
|
riot.mount @preview, do
|
||||||
|
url: t.content
|
||||||
|
</script>
|
||||||
|
</mk-messaging-message>
|
||||||
|
|
|
@ -1,26 +1,25 @@
|
||||||
mk-messaging-room-window
|
<mk-messaging-room-window>
|
||||||
mk-window@window(is-modal={ false }, width={ '500px' }, height={ '560px' })
|
<mk-window ref="window" is-modal="{ false }" width="{ '500px' }" height="{ '560px' }"><yield to="header"><i class="fa fa-comments"></i>メッセージ: { parent.user.name }</yield>
|
||||||
<yield to="header">
|
<yield to="content">
|
||||||
i.fa.fa-comments
|
<mk-messaging-room user="{ parent.user }"></mk-messaging-room></yield>
|
||||||
| メッセージ: { parent.user.name }
|
</mk-window>
|
||||||
</yield>
|
<style type="stylus">
|
||||||
<yield to="content">
|
:scope
|
||||||
mk-messaging-room(user={ parent.user })
|
> mk-window
|
||||||
</yield>
|
[data-yield='header']
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
style.
|
[data-yield='content']
|
||||||
> mk-window
|
> mk-messaging-room
|
||||||
[data-yield='header']
|
height 100%
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
[data-yield='content']
|
</style>
|
||||||
> mk-messaging-room
|
<script>
|
||||||
height 100%
|
@user = @opts.user
|
||||||
|
|
||||||
script.
|
@on \mount ~>
|
||||||
@user = @opts.user
|
@refs.window.on \closed ~>
|
||||||
|
@unmount!
|
||||||
@on \mount ~>
|
</script>
|
||||||
@refs.window.on \closed ~>
|
</mk-messaging-room-window>
|
||||||
@unmount!
|
|
||||||
|
|
|
@ -1,227 +1,227 @@
|
||||||
mk-messaging-room
|
<mk-messaging-room>
|
||||||
div.stream@stream
|
<div class="stream" ref="stream">
|
||||||
p.initializing(if={ init })
|
<p class="initializing" if="{ init }"><i class="fa fa-spinner fa-spin"></i>読み込み中</p>
|
||||||
i.fa.fa-spinner.fa-spin
|
<p class="empty" if="{ !init && messages.length == 0 }"><i class="fa fa-info-circle"></i>このユーザーとまだ会話したことがありません</p>
|
||||||
| 読み込み中
|
<virtual each="{ message, i in messages }">
|
||||||
p.empty(if={ !init && messages.length == 0 })
|
<mk-messaging-message message="{ message }"></mk-messaging-message>
|
||||||
i.fa.fa-info-circle
|
<p class="date" if="{ i != messages.length - 1 && message._date != messages[i + 1]._date }"><span>{ messages[i + 1]._datetext }</span></p>
|
||||||
| このユーザーとまだ会話したことがありません
|
</virtual>
|
||||||
virtual(each={ message, i in messages })
|
</div>
|
||||||
mk-messaging-message(message={ message })
|
<div class="typings"></div>
|
||||||
p.date(if={ i != messages.length - 1 && message._date != messages[i + 1]._date })
|
<footer>
|
||||||
span { messages[i + 1]._datetext }
|
<div ref="notifications"></div>
|
||||||
|
<div class="grippie" title="ドラッグしてフォームの広さを調整"></div>
|
||||||
div.typings
|
<mk-messaging-form user="{ user }"></mk-messaging-form>
|
||||||
footer
|
</footer>
|
||||||
div@notifications
|
<style type="stylus">
|
||||||
div.grippie(title='ドラッグしてフォームの広さを調整')
|
:scope
|
||||||
mk-messaging-form(user={ user })
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
|
|
||||||
> .stream
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
width 100%
|
|
||||||
height calc(100% - 100px)
|
|
||||||
overflow auto
|
|
||||||
|
|
||||||
> .empty
|
|
||||||
width 100%
|
|
||||||
margin 0
|
|
||||||
padding 16px 8px 8px 8px
|
|
||||||
text-align center
|
|
||||||
font-size 0.8em
|
|
||||||
color rgba(0, 0, 0, 0.4)
|
|
||||||
|
|
||||||
i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
> .no-history
|
|
||||||
display block
|
display block
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
text-align center
|
|
||||||
font-size 0.8em
|
|
||||||
color rgba(0, 0, 0, 0.4)
|
|
||||||
|
|
||||||
i
|
> .stream
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
> .message
|
|
||||||
// something
|
|
||||||
|
|
||||||
> .date
|
|
||||||
display block
|
|
||||||
margin 8px 0
|
|
||||||
text-align center
|
|
||||||
|
|
||||||
&:before
|
|
||||||
content ''
|
|
||||||
display block
|
|
||||||
position absolute
|
position absolute
|
||||||
height 1px
|
top 0
|
||||||
width 90%
|
|
||||||
top 16px
|
|
||||||
left 0
|
left 0
|
||||||
right 0
|
width 100%
|
||||||
|
height calc(100% - 100px)
|
||||||
|
overflow auto
|
||||||
|
|
||||||
|
> .empty
|
||||||
|
width 100%
|
||||||
|
margin 0
|
||||||
|
padding 16px 8px 8px 8px
|
||||||
|
text-align center
|
||||||
|
font-size 0.8em
|
||||||
|
color rgba(0, 0, 0, 0.4)
|
||||||
|
|
||||||
|
i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
|
> .no-history
|
||||||
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
font-size 0.8em
|
||||||
|
color rgba(0, 0, 0, 0.4)
|
||||||
|
|
||||||
|
i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
|
> .message
|
||||||
|
// something
|
||||||
|
|
||||||
|
> .date
|
||||||
|
display block
|
||||||
|
margin 8px 0
|
||||||
|
text-align center
|
||||||
|
|
||||||
|
&:before
|
||||||
|
content ''
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
height 1px
|
||||||
|
width 90%
|
||||||
|
top 16px
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
margin 0 auto
|
||||||
|
background rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
|
> span
|
||||||
|
display inline-block
|
||||||
|
margin 0
|
||||||
|
padding 0 16px
|
||||||
|
//font-weight bold
|
||||||
|
line-height 32px
|
||||||
|
color rgba(0, 0, 0, 0.3)
|
||||||
|
background #fff
|
||||||
|
|
||||||
|
> footer
|
||||||
|
position absolute
|
||||||
|
z-index 2
|
||||||
|
bottom 0
|
||||||
|
width 600px
|
||||||
|
max-width 100%
|
||||||
margin 0 auto
|
margin 0 auto
|
||||||
background rgba(0, 0, 0, 0.1)
|
padding 0
|
||||||
|
background rgba(255, 255, 255, 0.95)
|
||||||
|
background-clip content-box
|
||||||
|
|
||||||
> span
|
> [ref='notifications']
|
||||||
display inline-block
|
|
||||||
margin 0
|
|
||||||
padding 0 16px
|
|
||||||
//font-weight bold
|
|
||||||
line-height 32px
|
|
||||||
color rgba(0, 0, 0, 0.3)
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
> footer
|
|
||||||
position absolute
|
|
||||||
z-index 2
|
|
||||||
bottom 0
|
|
||||||
width 600px
|
|
||||||
max-width 100%
|
|
||||||
margin 0 auto
|
|
||||||
padding 0
|
|
||||||
background rgba(255, 255, 255, 0.95)
|
|
||||||
background-clip content-box
|
|
||||||
|
|
||||||
> [ref='notifications']
|
|
||||||
position absolute
|
|
||||||
top -48px
|
|
||||||
width 100%
|
|
||||||
padding 8px 0
|
|
||||||
text-align center
|
|
||||||
|
|
||||||
> p
|
|
||||||
display inline-block
|
|
||||||
margin 0
|
|
||||||
padding 0 12px 0 28px
|
|
||||||
cursor pointer
|
|
||||||
line-height 32px
|
|
||||||
font-size 12px
|
|
||||||
color $theme-color-foreground
|
|
||||||
background $theme-color
|
|
||||||
border-radius 16px
|
|
||||||
transition opacity 1s ease
|
|
||||||
|
|
||||||
> i
|
|
||||||
position absolute
|
position absolute
|
||||||
top 0
|
top -48px
|
||||||
left 10px
|
width 100%
|
||||||
line-height 32px
|
padding 8px 0
|
||||||
font-size 16px
|
text-align center
|
||||||
|
|
||||||
> .grippie
|
> p
|
||||||
height 10px
|
display inline-block
|
||||||
margin-top -10px
|
margin 0
|
||||||
background transparent
|
padding 0 12px 0 28px
|
||||||
cursor ns-resize
|
cursor pointer
|
||||||
|
line-height 32px
|
||||||
|
font-size 12px
|
||||||
|
color $theme-color-foreground
|
||||||
|
background $theme-color
|
||||||
|
border-radius 16px
|
||||||
|
transition opacity 1s ease
|
||||||
|
|
||||||
&:hover
|
> i
|
||||||
//background rgba(0, 0, 0, 0.1)
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 10px
|
||||||
|
line-height 32px
|
||||||
|
font-size 16px
|
||||||
|
|
||||||
&:active
|
> .grippie
|
||||||
//background rgba(0, 0, 0, 0.2)
|
height 10px
|
||||||
|
margin-top -10px
|
||||||
|
background transparent
|
||||||
|
cursor ns-resize
|
||||||
|
|
||||||
script.
|
&:hover
|
||||||
@mixin \i
|
//background rgba(0, 0, 0, 0.1)
|
||||||
@mixin \api
|
|
||||||
@mixin \messaging-stream
|
|
||||||
|
|
||||||
@user = @opts.user
|
&:active
|
||||||
@init = true
|
//background rgba(0, 0, 0, 0.2)
|
||||||
@sending = false
|
|
||||||
@messages = []
|
|
||||||
|
|
||||||
@connection = new @MessagingStreamConnection @I, @user.id
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mixin \api
|
||||||
|
@mixin \messaging-stream
|
||||||
|
|
||||||
@on \mount ~>
|
@user = @opts.user
|
||||||
@connection.event.on \message @on-message
|
@init = true
|
||||||
@connection.event.on \read @on-read
|
@sending = false
|
||||||
|
@messages = []
|
||||||
|
|
||||||
document.add-event-listener \visibilitychange @on-visibilitychange
|
@connection = new @MessagingStreamConnection @I, @user.id
|
||||||
|
|
||||||
@api \messaging/messages do
|
@on \mount ~>
|
||||||
user_id: @user.id
|
@connection.event.on \message @on-message
|
||||||
.then (messages) ~>
|
@connection.event.on \read @on-read
|
||||||
@init = false
|
|
||||||
@messages = messages.reverse!
|
|
||||||
@update!
|
|
||||||
@scroll-to-bottom!
|
|
||||||
.catch (err) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@on \unmount ~>
|
document.add-event-listener \visibilitychange @on-visibilitychange
|
||||||
@connection.event.off \message @on-message
|
|
||||||
@connection.event.off \read @on-read
|
|
||||||
@connection.close!
|
|
||||||
|
|
||||||
document.remove-event-listener \visibilitychange @on-visibilitychange
|
@api \messaging/messages do
|
||||||
|
user_id: @user.id
|
||||||
@on \update ~>
|
.then (messages) ~>
|
||||||
@messages.for-each (message) ~>
|
@init = false
|
||||||
date = (new Date message.created_at).get-date!
|
@messages = messages.reverse!
|
||||||
month = (new Date message.created_at).get-month! + 1
|
|
||||||
message._date = date
|
|
||||||
message._datetext = month + '月 ' + date + '日'
|
|
||||||
|
|
||||||
@on-message = (message) ~>
|
|
||||||
is-bottom = @is-bottom!
|
|
||||||
|
|
||||||
@messages.push message
|
|
||||||
if message.user_id != @I.id and not document.hidden
|
|
||||||
@connection.socket.send JSON.stringify do
|
|
||||||
type: \read
|
|
||||||
id: message.id
|
|
||||||
@update!
|
|
||||||
|
|
||||||
if is-bottom
|
|
||||||
# Scroll to bottom
|
|
||||||
@scroll-to-bottom!
|
|
||||||
else if message.user_id != @I.id
|
|
||||||
# Notify
|
|
||||||
@notify '新しいメッセージがあります'
|
|
||||||
|
|
||||||
@on-read = (ids) ~>
|
|
||||||
if not Array.isArray ids then ids = [ids]
|
|
||||||
ids.for-each (id) ~>
|
|
||||||
if (@messages.some (x) ~> x.id == id)
|
|
||||||
exist = (@messages.map (x) -> x.id).index-of id
|
|
||||||
@messages[exist].is_read = true
|
|
||||||
@update!
|
@update!
|
||||||
|
@scroll-to-bottom!
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
@is-bottom = ~>
|
@on \unmount ~>
|
||||||
current = @refs.stream.scroll-top + @refs.stream.offset-height
|
@connection.event.off \message @on-message
|
||||||
max = @refs.stream.scroll-height
|
@connection.event.off \read @on-read
|
||||||
current > (max - 32)
|
@connection.close!
|
||||||
|
|
||||||
@scroll-to-bottom = ~>
|
document.remove-event-listener \visibilitychange @on-visibilitychange
|
||||||
@refs.stream.scroll-top = @refs.stream.scroll-height
|
|
||||||
|
|
||||||
@notify = (message) ~>
|
@on \update ~>
|
||||||
n = document.create-element \p
|
@messages.for-each (message) ~>
|
||||||
n.inner-HTML = '<i class="fa fa-arrow-circle-down"></i>' + message
|
date = (new Date message.created_at).get-date!
|
||||||
n.onclick = ~>
|
month = (new Date message.created_at).get-month! + 1
|
||||||
@scroll-to-bottom!
|
message._date = date
|
||||||
n.parent-node.remove-child n
|
message._datetext = month + '月 ' + date + '日'
|
||||||
@refs.notifications.append-child n
|
|
||||||
|
|
||||||
set-timeout ~>
|
@on-message = (message) ~>
|
||||||
n.style.opacity = 0
|
is-bottom = @is-bottom!
|
||||||
set-timeout ~>
|
|
||||||
n.parent-node.remove-child n
|
|
||||||
, 1000ms
|
|
||||||
, 4000ms
|
|
||||||
|
|
||||||
@on-visibilitychange = ~>
|
@messages.push message
|
||||||
if document.hidden then return
|
if message.user_id != @I.id and not document.hidden
|
||||||
@messages.for-each (message) ~>
|
|
||||||
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
|
||||||
|
@update!
|
||||||
|
|
||||||
|
if is-bottom
|
||||||
|
# Scroll to bottom
|
||||||
|
@scroll-to-bottom!
|
||||||
|
else if message.user_id != @I.id
|
||||||
|
# Notify
|
||||||
|
@notify '新しいメッセージがあります'
|
||||||
|
|
||||||
|
@on-read = (ids) ~>
|
||||||
|
if not Array.isArray ids then ids = [ids]
|
||||||
|
ids.for-each (id) ~>
|
||||||
|
if (@messages.some (x) ~> x.id == id)
|
||||||
|
exist = (@messages.map (x) -> x.id).index-of id
|
||||||
|
@messages[exist].is_read = true
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@is-bottom = ~>
|
||||||
|
current = @refs.stream.scroll-top + @refs.stream.offset-height
|
||||||
|
max = @refs.stream.scroll-height
|
||||||
|
current > (max - 32)
|
||||||
|
|
||||||
|
@scroll-to-bottom = ~>
|
||||||
|
@refs.stream.scroll-top = @refs.stream.scroll-height
|
||||||
|
|
||||||
|
@notify = (message) ~>
|
||||||
|
n = document.create-element \p
|
||||||
|
n.inner-HTML = '<i class="fa fa-arrow-circle-down"></i>' + message
|
||||||
|
n.onclick = ~>
|
||||||
|
@scroll-to-bottom!
|
||||||
|
n.parent-node.remove-child n
|
||||||
|
@refs.notifications.append-child n
|
||||||
|
|
||||||
|
set-timeout ~>
|
||||||
|
n.style.opacity = 0
|
||||||
|
set-timeout ~>
|
||||||
|
n.parent-node.remove-child n
|
||||||
|
, 1000ms
|
||||||
|
, 4000ms
|
||||||
|
|
||||||
|
@on-visibilitychange = ~>
|
||||||
|
if document.hidden then return
|
||||||
|
@messages.for-each (message) ~>
|
||||||
|
if message.user_id != @I.id and not message.is_read
|
||||||
|
@connection.socket.send JSON.stringify do
|
||||||
|
type: \read
|
||||||
|
id: message.id
|
||||||
|
</script>
|
||||||
|
</mk-messaging-room>
|
||||||
|
|
|
@ -1,29 +1,28 @@
|
||||||
mk-messaging-window
|
<mk-messaging-window>
|
||||||
mk-window@window(is-modal={ false }, width={ '500px' }, height={ '560px' })
|
<mk-window ref="window" is-modal="{ false }" width="{ '500px' }" height="{ '560px' }"><yield to="header"><i class="fa fa-comments"></i>メッセージ</yield>
|
||||||
<yield to="header">
|
<yield to="content">
|
||||||
i.fa.fa-comments
|
<mk-messaging ref="index"></mk-messaging></yield>
|
||||||
| メッセージ
|
</mk-window>
|
||||||
</yield>
|
<style type="stylus">
|
||||||
<yield to="content">
|
:scope
|
||||||
mk-messaging@index
|
> mk-window
|
||||||
</yield>
|
[data-yield='header']
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
style.
|
[data-yield='content']
|
||||||
> mk-window
|
> mk-messaging
|
||||||
[data-yield='header']
|
height 100%
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
[data-yield='content']
|
</style>
|
||||||
> mk-messaging
|
<script>
|
||||||
height 100%
|
@on \mount ~>
|
||||||
|
@refs.window.on \closed ~>
|
||||||
|
@unmount!
|
||||||
|
|
||||||
script.
|
@refs.window.refs.index.on \navigate-user (user) ~>
|
||||||
@on \mount ~>
|
w = document.body.append-child document.create-element \mk-messaging-room-window
|
||||||
@refs.window.on \closed ~>
|
riot.mount w, do
|
||||||
@unmount!
|
user: user
|
||||||
|
</script>
|
||||||
@refs.window.refs.index.on \navigate-user (user) ~>
|
</mk-messaging-window>
|
||||||
w = document.body.append-child document.create-element \mk-messaging-room-window
|
|
||||||
riot.mount w, do
|
|
||||||
user: user
|
|
||||||
|
|
|
@ -1,226 +1,199 @@
|
||||||
mk-notifications
|
<mk-notifications>
|
||||||
div.notifications(if={ notifications.length != 0 })
|
<div class="notifications" if="{ notifications.length != 0 }">
|
||||||
virtual(each={ notification, i in notifications })
|
<virtual each="{ notification, i in notifications }">
|
||||||
div.notification(class={ notification.type })
|
<div class="notification { notification.type }">
|
||||||
mk-time(time={ notification.created_at })
|
<mk-time time="{ notification.created_at }"></mk-time>
|
||||||
|
<div class="main" if="{ notification.type == 'like' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.user.username }" data-user-preview="{ notification.user.id }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&size=48' }" alt="avatar"/></a>
|
||||||
|
<div class="text">
|
||||||
|
<p><i class="fa fa-thumbs-o-up"></i><a href="{ CONFIG.url + '/' + notification.user.username }" data-user-preview="{ notification.user.id }">{ notification.user.name }</a></p><a class="post-ref" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main" if="{ notification.type == 'repost' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=48' }" alt="avatar"/></a>
|
||||||
|
<div class="text">
|
||||||
|
<p><i class="fa fa-retweet"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }">{ notification.post.user.name }</a></p><a class="post-ref" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post.repost) }</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main" if="{ notification.type == 'quote' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=48' }" alt="avatar"/></a>
|
||||||
|
<div class="text">
|
||||||
|
<p><i class="fa fa-quote-left"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }">{ notification.post.user.name }</a></p><a class="post-preview" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main" if="{ notification.type == 'follow' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.user.username }" data-user-preview="{ notification.user.id }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&size=48' }" alt="avatar"/></a>
|
||||||
|
<div class="text">
|
||||||
|
<p><i class="fa fa-user-plus"></i><a href="{ CONFIG.url + '/' + notification.user.username }" data-user-preview="{ notification.user.id }">{ notification.user.name }</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main" if="{ notification.type == 'reply' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=48' }" alt="avatar"/></a>
|
||||||
|
<div class="text">
|
||||||
|
<p><i class="fa fa-reply"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }">{ notification.post.user.name }</a></p><a class="post-preview" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main" if="{ notification.type == 'mention' }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=48' }" alt="avatar"/></a>
|
||||||
|
<div class="text">
|
||||||
|
<p><i class="fa fa-at"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }" data-user-preview="{ notification.post.user_id }">{ notification.post.user.name }</a></p><a class="post-preview" href="{ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }">{ getPostSummary(notification.post) }</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="date" if="{ i != notifications.length - 1 && notification._date != notifications[i + 1]._date }"><span><i class="fa fa-angle-up"></i>{ notification._datetext }</span><span><i class="fa fa-angle-down"></i>{ notifications[i + 1]._datetext }</span></p>
|
||||||
|
</virtual>
|
||||||
|
</div>
|
||||||
|
<p class="empty" if="{ notifications.length == 0 && !loading }">ありません!</p>
|
||||||
|
<p class="loading" if="{ loading }"><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
|
||||||
|
<mk-ellipsis></mk-ellipsis>
|
||||||
|
</p>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
div.main(if={ notification.type == 'like' })
|
> .notifications
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + notification.user.username }, data-user-preview={ notification.user.id })
|
> .notification
|
||||||
img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
|
|
||||||
div.text
|
|
||||||
p
|
|
||||||
i.fa.fa-thumbs-o-up
|
|
||||||
a(href={ CONFIG.url + '/' + notification.user.username }, data-user-preview={ notification.user.id }) { notification.user.name }
|
|
||||||
a.post-ref(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
|
|
||||||
|
|
||||||
div.main(if={ notification.type == 'repost' })
|
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id })
|
|
||||||
img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
|
|
||||||
div.text
|
|
||||||
p
|
|
||||||
i.fa.fa-retweet
|
|
||||||
a(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id }) { notification.post.user.name }
|
|
||||||
a.post-ref(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post.repost) }
|
|
||||||
|
|
||||||
div.main(if={ notification.type == 'quote' })
|
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id })
|
|
||||||
img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
|
|
||||||
div.text
|
|
||||||
p
|
|
||||||
i.fa.fa-quote-left
|
|
||||||
a(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id }) { notification.post.user.name }
|
|
||||||
a.post-preview(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
|
|
||||||
|
|
||||||
div.main(if={ notification.type == 'follow' })
|
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + notification.user.username }, data-user-preview={ notification.user.id })
|
|
||||||
img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
|
|
||||||
div.text
|
|
||||||
p
|
|
||||||
i.fa.fa-user-plus
|
|
||||||
a(href={ CONFIG.url + '/' + notification.user.username }, data-user-preview={ notification.user.id }) { notification.user.name }
|
|
||||||
|
|
||||||
div.main(if={ notification.type == 'reply' })
|
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id })
|
|
||||||
img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
|
|
||||||
div.text
|
|
||||||
p
|
|
||||||
i.fa.fa-reply
|
|
||||||
a(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id }) { notification.post.user.name }
|
|
||||||
a.post-preview(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
|
|
||||||
|
|
||||||
div.main(if={ notification.type == 'mention' })
|
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id })
|
|
||||||
img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=48' }, alt='avatar')
|
|
||||||
div.text
|
|
||||||
p
|
|
||||||
i.fa.fa-at
|
|
||||||
a(href={ CONFIG.url + '/' + notification.post.user.username }, data-user-preview={ notification.post.user_id }) { notification.post.user.name }
|
|
||||||
a.post-preview(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) }
|
|
||||||
|
|
||||||
p.date(if={ i != notifications.length - 1 && notification._date != notifications[i + 1]._date })
|
|
||||||
span
|
|
||||||
i.fa.fa-angle-up
|
|
||||||
| { notification._datetext }
|
|
||||||
span
|
|
||||||
i.fa.fa-angle-down
|
|
||||||
| { notifications[i + 1]._datetext }
|
|
||||||
|
|
||||||
p.empty(if={ notifications.length == 0 && !loading })
|
|
||||||
| ありません!
|
|
||||||
p.loading(if={ loading })
|
|
||||||
i.fa.fa-spinner.fa-pulse.fa-fw
|
|
||||||
| 読み込んでいます
|
|
||||||
mk-ellipsis
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
|
|
||||||
> .notifications
|
|
||||||
> .notification
|
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
font-size 0.9em
|
|
||||||
border-bottom solid 1px rgba(0, 0, 0, 0.05)
|
|
||||||
|
|
||||||
&:last-child
|
|
||||||
border-bottom none
|
|
||||||
|
|
||||||
> mk-time
|
|
||||||
display inline
|
|
||||||
position absolute
|
|
||||||
top 16px
|
|
||||||
right 12px
|
|
||||||
vertical-align top
|
|
||||||
color rgba(0, 0, 0, 0.6)
|
|
||||||
font-size small
|
|
||||||
|
|
||||||
> .main
|
|
||||||
word-wrap break-word
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
.avatar-anchor
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
|
|
||||||
img
|
|
||||||
min-width 36px
|
|
||||||
min-height 36px
|
|
||||||
max-width 36px
|
|
||||||
max-height 36px
|
|
||||||
border-radius 6px
|
|
||||||
|
|
||||||
.text
|
|
||||||
float right
|
|
||||||
width calc(100% - 36px)
|
|
||||||
padding-left 8px
|
|
||||||
|
|
||||||
p
|
|
||||||
margin 0
|
margin 0
|
||||||
|
padding 16px
|
||||||
|
font-size 0.9em
|
||||||
|
border-bottom solid 1px rgba(0, 0, 0, 0.05)
|
||||||
|
|
||||||
|
&:last-child
|
||||||
|
border-bottom none
|
||||||
|
|
||||||
|
> mk-time
|
||||||
|
display inline
|
||||||
|
position absolute
|
||||||
|
top 16px
|
||||||
|
right 12px
|
||||||
|
vertical-align top
|
||||||
|
color rgba(0, 0, 0, 0.6)
|
||||||
|
font-size small
|
||||||
|
|
||||||
|
> .main
|
||||||
|
word-wrap break-word
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ""
|
||||||
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
|
.avatar-anchor
|
||||||
|
display block
|
||||||
|
float left
|
||||||
|
|
||||||
|
img
|
||||||
|
min-width 36px
|
||||||
|
min-height 36px
|
||||||
|
max-width 36px
|
||||||
|
max-height 36px
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
.text
|
||||||
|
float right
|
||||||
|
width calc(100% - 36px)
|
||||||
|
padding-left 8px
|
||||||
|
|
||||||
|
p
|
||||||
|
margin 0
|
||||||
|
|
||||||
|
i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
|
.post-preview
|
||||||
|
color rgba(0, 0, 0, 0.7)
|
||||||
|
|
||||||
|
.post-ref
|
||||||
|
color rgba(0, 0, 0, 0.7)
|
||||||
|
|
||||||
|
&:before, &:after
|
||||||
|
font-family FontAwesome
|
||||||
|
font-size 1em
|
||||||
|
font-weight normal
|
||||||
|
font-style normal
|
||||||
|
display inline-block
|
||||||
|
margin-right 3px
|
||||||
|
|
||||||
|
&:before
|
||||||
|
content "\f10d"
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content "\f10e"
|
||||||
|
|
||||||
|
&.like
|
||||||
|
.text p i
|
||||||
|
color #FFAC33
|
||||||
|
|
||||||
|
&.repost, &.quote
|
||||||
|
.text p i
|
||||||
|
color #77B255
|
||||||
|
|
||||||
|
&.follow
|
||||||
|
.text p i
|
||||||
|
color #53c7ce
|
||||||
|
|
||||||
|
&.reply, &.mention
|
||||||
|
.text p i
|
||||||
|
color #555
|
||||||
|
|
||||||
|
> .date
|
||||||
|
display block
|
||||||
|
margin 0
|
||||||
|
line-height 32px
|
||||||
|
text-align center
|
||||||
|
font-size 0.8em
|
||||||
|
color #aaa
|
||||||
|
background #fdfdfd
|
||||||
|
border-bottom solid 1px rgba(0, 0, 0, 0.05)
|
||||||
|
|
||||||
|
span
|
||||||
|
margin 0 16px
|
||||||
|
|
||||||
i
|
i
|
||||||
margin-right 4px
|
margin-right 8px
|
||||||
|
|
||||||
.post-preview
|
> .empty
|
||||||
color rgba(0, 0, 0, 0.7)
|
margin 0
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color #aaa
|
||||||
|
|
||||||
.post-ref
|
> .loading
|
||||||
color rgba(0, 0, 0, 0.7)
|
margin 0
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color #aaa
|
||||||
|
|
||||||
&:before, &:after
|
> i
|
||||||
font-family FontAwesome
|
margin-right 4px
|
||||||
font-size 1em
|
|
||||||
font-weight normal
|
|
||||||
font-style normal
|
|
||||||
display inline-block
|
|
||||||
margin-right 3px
|
|
||||||
|
|
||||||
&:before
|
</style>
|
||||||
content "\f10d"
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \stream
|
||||||
|
@mixin \user-preview
|
||||||
|
@mixin \get-post-summary
|
||||||
|
|
||||||
&:after
|
@notifications = []
|
||||||
content "\f10e"
|
@loading = true
|
||||||
|
|
||||||
&.like
|
@on \mount ~>
|
||||||
.text p i
|
@api \i/notifications
|
||||||
color #FFAC33
|
.then (notifications) ~>
|
||||||
|
@notifications = notifications
|
||||||
|
@loading = false
|
||||||
|
@update!
|
||||||
|
.catch (err, text-status) ->
|
||||||
|
console.error err
|
||||||
|
|
||||||
&.repost, &.quote
|
@stream.on \notification @on-notification
|
||||||
.text p i
|
|
||||||
color #77B255
|
|
||||||
|
|
||||||
&.follow
|
@on \unmount ~>
|
||||||
.text p i
|
@stream.off \notification @on-notification
|
||||||
color #53c7ce
|
|
||||||
|
|
||||||
&.reply, &.mention
|
@on-notification = (notification) ~>
|
||||||
.text p i
|
@notifications.unshift notification
|
||||||
color #555
|
|
||||||
|
|
||||||
> .date
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
line-height 32px
|
|
||||||
text-align center
|
|
||||||
font-size 0.8em
|
|
||||||
color #aaa
|
|
||||||
background #fdfdfd
|
|
||||||
border-bottom solid 1px rgba(0, 0, 0, 0.05)
|
|
||||||
|
|
||||||
span
|
|
||||||
margin 0 16px
|
|
||||||
|
|
||||||
i
|
|
||||||
margin-right 8px
|
|
||||||
|
|
||||||
> .empty
|
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
text-align center
|
|
||||||
color #aaa
|
|
||||||
|
|
||||||
> .loading
|
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
text-align center
|
|
||||||
color #aaa
|
|
||||||
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
script.
|
|
||||||
@mixin \api
|
|
||||||
@mixin \stream
|
|
||||||
@mixin \user-preview
|
|
||||||
@mixin \get-post-summary
|
|
||||||
|
|
||||||
@notifications = []
|
|
||||||
@loading = true
|
|
||||||
|
|
||||||
@on \mount ~>
|
|
||||||
@api \i/notifications
|
|
||||||
.then (notifications) ~>
|
|
||||||
@notifications = notifications
|
|
||||||
@loading = false
|
|
||||||
@update!
|
@update!
|
||||||
.catch (err, text-status) ->
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@stream.on \notification @on-notification
|
@on \update ~>
|
||||||
|
@notifications.for-each (notification) ~>
|
||||||
@on \unmount ~>
|
date = (new Date notification.created_at).get-date!
|
||||||
@stream.off \notification @on-notification
|
month = (new Date notification.created_at).get-month! + 1
|
||||||
|
notification._date = date
|
||||||
@on-notification = (notification) ~>
|
notification._datetext = month + '月 ' + date + '日'
|
||||||
@notifications.unshift notification
|
</script>
|
||||||
@update!
|
</mk-notifications>
|
||||||
|
|
||||||
@on \update ~>
|
|
||||||
@notifications.for-each (notification) ~>
|
|
||||||
date = (new Date notification.created_at).get-date!
|
|
||||||
month = (new Date notification.created_at).get-month! + 1
|
|
||||||
notification._date = date
|
|
||||||
notification._datetext = month + '月 ' + date + '日'
|
|
||||||
|
|
|
@ -1,77 +1,80 @@
|
||||||
mk-entrance
|
<mk-entrance>
|
||||||
main
|
<main><img src="/_/resources/title.svg" alt="Misskey"/>
|
||||||
img(src='/_/resources/title.svg', alt='Misskey')
|
<mk-entrance-signin if="{ mode == 'signin' }"></mk-entrance-signin>
|
||||||
|
<mk-entrance-signup if="{ mode == 'signup' }"></mk-entrance-signup>
|
||||||
mk-entrance-signin(if={ mode == 'signin' })
|
<div class="introduction" if="{ mode == 'introduction' }">
|
||||||
mk-entrance-signup(if={ mode == 'signup' })
|
<mk-introduction></mk-introduction>
|
||||||
div.introduction(if={ mode == 'introduction' })
|
<button onclick="{ signin }">わかった</button>
|
||||||
mk-introduction
|
</div>
|
||||||
button(onclick={ signin }) わかった
|
</main>
|
||||||
|
<mk-forkit></mk-forkit>
|
||||||
mk-forkit
|
<footer>
|
||||||
|
<mk-copyright></mk-copyright>
|
||||||
footer
|
</footer>
|
||||||
mk-copyright
|
<!-- ↓ https://github.com/riot/riot/issues/2134 (将来的)-->
|
||||||
|
<style data-disable-scope="data-disable-scope">
|
||||||
// ↓ https://github.com/riot/riot/issues/2134 (将来的)
|
|
||||||
style(data-disable-scope).
|
|
||||||
#wait {
|
#wait {
|
||||||
right: auto;
|
right: auto;
|
||||||
left: 15px;
|
left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
style.
|
</style>
|
||||||
display block
|
<style type="stylus">
|
||||||
height 100%
|
:scope
|
||||||
|
|
||||||
> main
|
|
||||||
display block
|
|
||||||
|
|
||||||
> img
|
|
||||||
display block
|
display block
|
||||||
width 160px
|
height 100%
|
||||||
height 170px
|
|
||||||
margin 0 auto
|
|
||||||
pointer-events none
|
|
||||||
user-select none
|
|
||||||
|
|
||||||
> .introduction
|
> main
|
||||||
max-width 360px
|
|
||||||
margin 0 auto
|
|
||||||
color #777
|
|
||||||
|
|
||||||
> mk-introduction
|
|
||||||
padding 32px
|
|
||||||
background #fff
|
|
||||||
box-shadow 0 4px 16px rgba(0, 0, 0, 0.2)
|
|
||||||
|
|
||||||
> button
|
|
||||||
display block
|
display block
|
||||||
margin 16px auto 0 auto
|
|
||||||
color #666
|
|
||||||
|
|
||||||
&:hover
|
> img
|
||||||
text-decoration underline
|
display block
|
||||||
|
width 160px
|
||||||
|
height 170px
|
||||||
|
margin 0 auto
|
||||||
|
pointer-events none
|
||||||
|
user-select none
|
||||||
|
|
||||||
> footer
|
> .introduction
|
||||||
> mk-copyright
|
max-width 360px
|
||||||
margin 0
|
margin 0 auto
|
||||||
text-align center
|
color #777
|
||||||
line-height 64px
|
|
||||||
font-size 10px
|
|
||||||
color rgba(#000, 0.5)
|
|
||||||
|
|
||||||
script.
|
> mk-introduction
|
||||||
@mode = \signin
|
padding 32px
|
||||||
|
background #fff
|
||||||
|
box-shadow 0 4px 16px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
@signup = ~>
|
> button
|
||||||
@mode = \signup
|
display block
|
||||||
@update!
|
margin 16px auto 0 auto
|
||||||
|
color #666
|
||||||
|
|
||||||
@signin = ~>
|
&:hover
|
||||||
|
text-decoration underline
|
||||||
|
|
||||||
|
> footer
|
||||||
|
> mk-copyright
|
||||||
|
margin 0
|
||||||
|
text-align center
|
||||||
|
line-height 64px
|
||||||
|
font-size 10px
|
||||||
|
color rgba(#000, 0.5)
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
@mode = \signin
|
@mode = \signin
|
||||||
@update!
|
|
||||||
|
|
||||||
@introduction = ~>
|
@signup = ~>
|
||||||
@mode = \introduction
|
@mode = \signup
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
|
@signin = ~>
|
||||||
|
@mode = \signin
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@introduction = ~>
|
||||||
|
@mode = \introduction
|
||||||
|
@update!
|
||||||
|
</script>
|
||||||
|
</mk-entrance>
|
||||||
|
|
|
@ -1,128 +1,130 @@
|
||||||
mk-entrance-signin
|
<mk-entrance-signin><a class="help" href="{ CONFIG.urls.about + '/help' }" title="お困りですか?"><i class="fa fa-question"></i></a>
|
||||||
a.help(href={ CONFIG.urls.about + '/help' }, title='お困りですか?'): i.fa.fa-question
|
<div class="form">
|
||||||
div.form
|
<h1><img if="{ user }" src="{ user.avatar_url + '?thumbnail&size=32' }"/>
|
||||||
h1
|
<p>{ user ? user.name : 'アカウント' }</p>
|
||||||
img(if={ user }, src={ user.avatar_url + '?thumbnail&size=32' })
|
</h1>
|
||||||
p { user ? user.name : 'アカウント' }
|
<mk-signin ref="signin"></mk-signin>
|
||||||
mk-signin@signin
|
</div>
|
||||||
div.divider: span or
|
<div class="divider"><span>or</span></div>
|
||||||
button.signup(onclick={ parent.signup }) 新規登録
|
<button class="signup" onclick="{ parent.signup }">新規登録</button><a class="introduction" onclick="{ introduction }">Misskeyについて</a>
|
||||||
a.introduction(onclick={ introduction }) Misskeyについて
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
style.
|
|
||||||
display block
|
|
||||||
width 290px
|
|
||||||
margin 0 auto
|
|
||||||
text-align center
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
> .help
|
|
||||||
opacity 1
|
|
||||||
|
|
||||||
> .help
|
|
||||||
cursor pointer
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
z-index 1
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
font-size 1.2em
|
|
||||||
color #999
|
|
||||||
border none
|
|
||||||
outline none
|
|
||||||
background transparent
|
|
||||||
opacity 0
|
|
||||||
transition opacity 0.1s ease
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color #444
|
|
||||||
|
|
||||||
&:active
|
|
||||||
color #222
|
|
||||||
|
|
||||||
> i
|
|
||||||
padding 14px
|
|
||||||
|
|
||||||
> .form
|
|
||||||
padding 10px 28px 16px 28px
|
|
||||||
background #fff
|
|
||||||
box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
|
|
||||||
|
|
||||||
> h1
|
|
||||||
display block
|
display block
|
||||||
margin 0
|
width 290px
|
||||||
padding 0
|
margin 0 auto
|
||||||
height 54px
|
|
||||||
line-height 54px
|
|
||||||
text-align center
|
text-align center
|
||||||
text-transform uppercase
|
|
||||||
font-size 1em
|
|
||||||
font-weight bold
|
|
||||||
color rgba(0, 0, 0, 0.5)
|
|
||||||
border-bottom solid 1px rgba(0, 0, 0, 0.1)
|
|
||||||
|
|
||||||
> p
|
&:hover
|
||||||
display inline
|
> .help
|
||||||
|
opacity 1
|
||||||
|
|
||||||
|
> .help
|
||||||
|
cursor pointer
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
right 0
|
||||||
|
z-index 1
|
||||||
margin 0
|
margin 0
|
||||||
padding 0
|
padding 0
|
||||||
|
font-size 1.2em
|
||||||
|
color #999
|
||||||
|
border none
|
||||||
|
outline none
|
||||||
|
background transparent
|
||||||
|
opacity 0
|
||||||
|
transition opacity 0.1s ease
|
||||||
|
|
||||||
> img
|
&:hover
|
||||||
|
color #444
|
||||||
|
|
||||||
|
&:active
|
||||||
|
color #222
|
||||||
|
|
||||||
|
> i
|
||||||
|
padding 14px
|
||||||
|
|
||||||
|
> .form
|
||||||
|
padding 10px 28px 16px 28px
|
||||||
|
background #fff
|
||||||
|
box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
|
> h1
|
||||||
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
height 54px
|
||||||
|
line-height 54px
|
||||||
|
text-align center
|
||||||
|
text-transform uppercase
|
||||||
|
font-size 1em
|
||||||
|
font-weight bold
|
||||||
|
color rgba(0, 0, 0, 0.5)
|
||||||
|
border-bottom solid 1px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
|
> p
|
||||||
|
display inline
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
|
||||||
|
> img
|
||||||
|
display inline-block
|
||||||
|
top 10px
|
||||||
|
width 32px
|
||||||
|
height 32px
|
||||||
|
margin-right 8px
|
||||||
|
border-radius 100%
|
||||||
|
|
||||||
|
&[src='']
|
||||||
|
display none
|
||||||
|
|
||||||
|
> .divider
|
||||||
|
padding 16px 0
|
||||||
|
text-align center
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ""
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top 50%
|
||||||
|
width 100%
|
||||||
|
height 1px
|
||||||
|
border-top solid 1px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
|
> *
|
||||||
|
z-index 1
|
||||||
|
padding 0 8px
|
||||||
|
color rgba(0, 0, 0, 0.5)
|
||||||
|
background #fdfdfd
|
||||||
|
|
||||||
|
> .signup
|
||||||
|
width 100%
|
||||||
|
line-height 56px
|
||||||
|
font-size 1em
|
||||||
|
color #fff
|
||||||
|
background $theme-color
|
||||||
|
border-radius 64px
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background lighten($theme-color, 5%)
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background darken($theme-color, 5%)
|
||||||
|
|
||||||
|
> .introduction
|
||||||
display inline-block
|
display inline-block
|
||||||
top 10px
|
margin-top 16px
|
||||||
width 32px
|
font-size 12px
|
||||||
height 32px
|
color #666
|
||||||
margin-right 8px
|
|
||||||
border-radius 100%
|
|
||||||
|
|
||||||
&[src='']
|
</style>
|
||||||
display none
|
<script>
|
||||||
|
@on \mount ~>
|
||||||
|
@refs.signin.on \user (user) ~>
|
||||||
|
@update do
|
||||||
|
user: user
|
||||||
|
|
||||||
> .divider
|
@introduction = ~>
|
||||||
padding 16px 0
|
@parent.introduction!
|
||||||
text-align center
|
</script>
|
||||||
|
</mk-entrance-signin>
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 50%
|
|
||||||
width 100%
|
|
||||||
height 1px
|
|
||||||
border-top solid 1px rgba(0, 0, 0, 0.1)
|
|
||||||
|
|
||||||
> *
|
|
||||||
z-index 1
|
|
||||||
padding 0 8px
|
|
||||||
color rgba(0, 0, 0, 0.5)
|
|
||||||
background #fdfdfd
|
|
||||||
|
|
||||||
> .signup
|
|
||||||
width 100%
|
|
||||||
line-height 56px
|
|
||||||
font-size 1em
|
|
||||||
color #fff
|
|
||||||
background $theme-color
|
|
||||||
border-radius 64px
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background lighten($theme-color, 5%)
|
|
||||||
|
|
||||||
&:active
|
|
||||||
background darken($theme-color, 5%)
|
|
||||||
|
|
||||||
> .introduction
|
|
||||||
display inline-block
|
|
||||||
margin-top 16px
|
|
||||||
font-size 12px
|
|
||||||
color #666
|
|
||||||
|
|
||||||
script.
|
|
||||||
@on \mount ~>
|
|
||||||
@refs.signin.on \user (user) ~>
|
|
||||||
@update do
|
|
||||||
user: user
|
|
||||||
|
|
||||||
@introduction = ~>
|
|
||||||
@parent.introduction!
|
|
||||||
|
|
|
@ -1,44 +1,51 @@
|
||||||
mk-entrance-signup
|
<mk-entrance-signup>
|
||||||
mk-signup
|
<mk-signup></mk-signup>
|
||||||
button.cancel(type='button', onclick={ parent.signin }, title='キャンセル'): i.fa.fa-times
|
<button class="cancel" type="button" onclick="{ parent.signin }" title="キャンセル"><i class="fa fa-times"></i></button>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
width 368px
|
||||||
|
margin 0 auto
|
||||||
|
|
||||||
style.
|
&:hover
|
||||||
display block
|
> .cancel
|
||||||
width 368px
|
opacity 1
|
||||||
margin 0 auto
|
|
||||||
|
|
||||||
&:hover
|
> mk-signup
|
||||||
> .cancel
|
padding 18px 32px 0 32px
|
||||||
opacity 1
|
background #fff
|
||||||
|
box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
> mk-signup
|
> .cancel
|
||||||
padding 18px 32px 0 32px
|
cursor pointer
|
||||||
background #fff
|
display block
|
||||||
box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2)
|
position absolute
|
||||||
|
top 0
|
||||||
|
right 0
|
||||||
|
z-index 1
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
font-size 1.2em
|
||||||
|
color #999
|
||||||
|
border none
|
||||||
|
outline none
|
||||||
|
box-shadow none
|
||||||
|
background transparent
|
||||||
|
opacity 0
|
||||||
|
transition opacity 0.1s ease
|
||||||
|
|
||||||
> .cancel
|
&:hover
|
||||||
cursor pointer
|
color #555
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
z-index 1
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
font-size 1.2em
|
|
||||||
color #999
|
|
||||||
border none
|
|
||||||
outline none
|
|
||||||
box-shadow none
|
|
||||||
background transparent
|
|
||||||
opacity 0
|
|
||||||
transition opacity 0.1s ease
|
|
||||||
|
|
||||||
&:hover
|
&:active
|
||||||
color #555
|
color #222
|
||||||
|
|
||||||
&:active
|
> i
|
||||||
color #222
|
padding 14px
|
||||||
|
|
||||||
> i
|
|
||||||
padding 14px
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</mk-entrance-signup>
|
||||||
|
|
|
@ -1,51 +1,56 @@
|
||||||
mk-home-page
|
<mk-home-page>
|
||||||
mk-ui@ui(page={ page }): mk-home@home(mode={ parent.opts.mode })
|
<mk-ui ref="ui" page="{ page }">
|
||||||
|
<mk-home ref="home" mode="{ parent.opts.mode }"></mk-home>
|
||||||
|
</mk-ui>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
background-position center center
|
||||||
display block
|
background-attachment fixed
|
||||||
|
background-size cover
|
||||||
|
|
||||||
background-position center center
|
</style>
|
||||||
background-attachment fixed
|
<script>
|
||||||
background-size cover
|
@mixin \i
|
||||||
|
@mixin \api
|
||||||
|
@mixin \ui-progress
|
||||||
|
@mixin \stream
|
||||||
|
@mixin \get-post-summary
|
||||||
|
|
||||||
script.
|
@unread-count = 0
|
||||||
@mixin \i
|
|
||||||
@mixin \api
|
|
||||||
@mixin \ui-progress
|
|
||||||
@mixin \stream
|
|
||||||
@mixin \get-post-summary
|
|
||||||
|
|
||||||
@unread-count = 0
|
@page = switch @opts.mode
|
||||||
|
| \timelie => \home
|
||||||
|
| \mentions => \mentions
|
||||||
|
| _ => \home
|
||||||
|
|
||||||
@page = switch @opts.mode
|
@on \mount ~>
|
||||||
| \timelie => \home
|
@refs.ui.refs.home.on \loaded ~>
|
||||||
| \mentions => \mentions
|
@Progress.done!
|
||||||
| _ => \home
|
|
||||||
|
|
||||||
@on \mount ~>
|
|
||||||
@refs.ui.refs.home.on \loaded ~>
|
|
||||||
@Progress.done!
|
|
||||||
|
|
||||||
document.title = 'Misskey'
|
|
||||||
if @I.data.wallpaper
|
|
||||||
@api \drive/files/show do
|
|
||||||
file_id: @I.data.wallpaper
|
|
||||||
.then (file) ~>
|
|
||||||
@root.style.background-image = 'url(' + file.url + ')'
|
|
||||||
@Progress.start!
|
|
||||||
@stream.on \post @on-stream-post
|
|
||||||
document.add-event-listener \visibilitychange @window-on-visibilitychange, false
|
|
||||||
|
|
||||||
@on \unmount ~>
|
|
||||||
@stream.off \post @on-stream-post
|
|
||||||
document.remove-event-listener \visibilitychange @window-on-visibilitychange
|
|
||||||
|
|
||||||
@on-stream-post = (post) ~>
|
|
||||||
if document.hidden and post.user_id !== @I.id
|
|
||||||
@unread-count++
|
|
||||||
document.title = '(' + @unread-count + ') ' + @get-post-summary post
|
|
||||||
|
|
||||||
@window-on-visibilitychange = ~>
|
|
||||||
if !document.hidden
|
|
||||||
@unread-count = 0
|
|
||||||
document.title = 'Misskey'
|
document.title = 'Misskey'
|
||||||
|
if @I.data.wallpaper
|
||||||
|
@api \drive/files/show do
|
||||||
|
file_id: @I.data.wallpaper
|
||||||
|
.then (file) ~>
|
||||||
|
@root.style.background-image = 'url(' + file.url + ')'
|
||||||
|
@Progress.start!
|
||||||
|
@stream.on \post @on-stream-post
|
||||||
|
document.add-event-listener \visibilitychange @window-on-visibilitychange, false
|
||||||
|
|
||||||
|
@on \unmount ~>
|
||||||
|
@stream.off \post @on-stream-post
|
||||||
|
document.remove-event-listener \visibilitychange @window-on-visibilitychange
|
||||||
|
|
||||||
|
@on-stream-post = (post) ~>
|
||||||
|
if document.hidden and post.user_id !== @I.id
|
||||||
|
@unread-count++
|
||||||
|
document.title = '(' + @unread-count + ') ' + @get-post-summary post
|
||||||
|
|
||||||
|
@window-on-visibilitychange = ~>
|
||||||
|
if !document.hidden
|
||||||
|
@unread-count = 0
|
||||||
|
document.title = 'Misskey'
|
||||||
|
</script>
|
||||||
|
</mk-home-page>
|
||||||
|
|
|
@ -1,46 +1,54 @@
|
||||||
mk-not-found
|
<mk-not-found>
|
||||||
mk-ui
|
<mk-ui>
|
||||||
main
|
<main>
|
||||||
h1 Not Found
|
<h1>Not Found</h1><img src="/_/resources/rogge.jpg" alt=""/>
|
||||||
img(src='/_/resources/rogge.jpg', alt='')
|
<div class="mask"></div>
|
||||||
div.mask
|
</main>
|
||||||
|
</mk-ui>
|
||||||
style.
|
<style type="stylus">
|
||||||
display block
|
:scope
|
||||||
|
|
||||||
main
|
|
||||||
display block
|
|
||||||
width 600px
|
|
||||||
margin 32px auto
|
|
||||||
|
|
||||||
> img
|
|
||||||
display block
|
display block
|
||||||
width 600px
|
|
||||||
height 459px
|
|
||||||
pointer-events none
|
|
||||||
user-select none
|
|
||||||
border-radius 16px
|
|
||||||
box-shadow 0 0 16px rgba(0, 0, 0, 0.1)
|
|
||||||
|
|
||||||
> h1
|
main
|
||||||
display block
|
display block
|
||||||
margin 0
|
width 600px
|
||||||
padding 0
|
margin 32px auto
|
||||||
position absolute
|
|
||||||
top 260px
|
|
||||||
left 225px
|
|
||||||
transform rotate(-12deg)
|
|
||||||
z-index 2
|
|
||||||
color #444
|
|
||||||
font-size 24px
|
|
||||||
line-height 20px
|
|
||||||
|
|
||||||
> .mask
|
> img
|
||||||
position absolute
|
display block
|
||||||
top 262px
|
width 600px
|
||||||
left 217px
|
height 459px
|
||||||
width 126px
|
pointer-events none
|
||||||
height 18px
|
user-select none
|
||||||
transform rotate(-12deg)
|
border-radius 16px
|
||||||
background #D6D5DA
|
box-shadow 0 0 16px rgba(0, 0, 0, 0.1)
|
||||||
border-radius 2px 6px 7px 6px
|
|
||||||
|
> h1
|
||||||
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
position absolute
|
||||||
|
top 260px
|
||||||
|
left 225px
|
||||||
|
transform rotate(-12deg)
|
||||||
|
z-index 2
|
||||||
|
color #444
|
||||||
|
font-size 24px
|
||||||
|
line-height 20px
|
||||||
|
|
||||||
|
> .mask
|
||||||
|
position absolute
|
||||||
|
top 262px
|
||||||
|
left 217px
|
||||||
|
width 126px
|
||||||
|
height 18px
|
||||||
|
transform rotate(-12deg)
|
||||||
|
background #D6D5DA
|
||||||
|
border-radius 2px 6px 7px 6px
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</mk-not-found>
|
||||||
|
|
|
@ -1,25 +1,32 @@
|
||||||
mk-post-page
|
<mk-post-page>
|
||||||
mk-ui@ui: main: mk-post-detail@detail(post={ parent.post })
|
<mk-ui ref="ui">
|
||||||
|
<main>
|
||||||
|
<mk-post-detail ref="detail" post="{ parent.post }"></mk-post-detail>
|
||||||
|
</main>
|
||||||
|
</mk-ui>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
main
|
||||||
display block
|
padding 16px
|
||||||
|
|
||||||
main
|
> mk-post-detail
|
||||||
padding 16px
|
margin 0 auto
|
||||||
|
|
||||||
> mk-post-detail
|
</style>
|
||||||
margin 0 auto
|
<script>
|
||||||
|
@mixin \ui-progress
|
||||||
|
|
||||||
script.
|
@post = @opts.post
|
||||||
@mixin \ui-progress
|
|
||||||
|
|
||||||
@post = @opts.post
|
@on \mount ~>
|
||||||
|
@Progress.start!
|
||||||
|
|
||||||
@on \mount ~>
|
@refs.ui.refs.detail.on \post-fetched ~>
|
||||||
@Progress.start!
|
@Progress.set 0.5
|
||||||
|
|
||||||
@refs.ui.refs.detail.on \post-fetched ~>
|
@refs.ui.refs.detail.on \loaded ~>
|
||||||
@Progress.set 0.5
|
@Progress.done!
|
||||||
|
</script>
|
||||||
@refs.ui.refs.detail.on \loaded ~>
|
</mk-post-page>
|
||||||
@Progress.done!
|
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
mk-search-page
|
<mk-search-page>
|
||||||
mk-ui@ui: mk-search@search(query={ parent.opts.query })
|
<mk-ui ref="ui">
|
||||||
|
<mk-search ref="search" query="{ parent.opts.query }"></mk-search>
|
||||||
|
</mk-ui>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
</style>
|
||||||
display block
|
<script>
|
||||||
|
@mixin \ui-progress
|
||||||
|
|
||||||
script.
|
@on \mount ~>
|
||||||
@mixin \ui-progress
|
@Progress.start!
|
||||||
|
|
||||||
@on \mount ~>
|
@refs.ui.refs.search.on \loaded ~>
|
||||||
@Progress.start!
|
@Progress.done!
|
||||||
|
</script>
|
||||||
@refs.ui.refs.search.on \loaded ~>
|
</mk-search-page>
|
||||||
@Progress.done!
|
|
||||||
|
|
|
@ -1,20 +1,25 @@
|
||||||
mk-user-page
|
<mk-user-page>
|
||||||
mk-ui@ui: mk-user@user(user={ parent.user }, page={ parent.opts.page })
|
<mk-ui ref="ui">
|
||||||
|
<mk-user ref="user" user="{ parent.user }" page="{ parent.opts.page }"></mk-user>
|
||||||
|
</mk-ui>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
</style>
|
||||||
display block
|
<script>
|
||||||
|
@mixin \ui-progress
|
||||||
|
|
||||||
script.
|
@user = @opts.user
|
||||||
@mixin \ui-progress
|
|
||||||
|
|
||||||
@user = @opts.user
|
@on \mount ~>
|
||||||
|
@Progress.start!
|
||||||
|
|
||||||
@on \mount ~>
|
@refs.ui.refs.user.on \user-fetched (user) ~>
|
||||||
@Progress.start!
|
@Progress.set 0.5
|
||||||
|
document.title = user.name + ' | Misskey'
|
||||||
|
|
||||||
@refs.ui.refs.user.on \user-fetched (user) ~>
|
@refs.ui.refs.user.on \loaded ~>
|
||||||
@Progress.set 0.5
|
@Progress.done!
|
||||||
document.title = user.name + ' | Misskey'
|
</script>
|
||||||
|
</mk-user-page>
|
||||||
@refs.ui.refs.user.on \loaded ~>
|
|
||||||
@Progress.done!
|
|
||||||
|
|
|
@ -1,141 +1,140 @@
|
||||||
mk-post-detail-sub(title={ title })
|
<mk-post-detail-sub title="{ title }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar" data-user-preview="{ post.user_id }"/></a>
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username })
|
<div class="main">
|
||||||
img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ post.user_id })
|
<header>
|
||||||
div.main
|
<div class="left"><a class="name" href="{ CONFIG.url + '/' + post.user.username }" data-user-preview="{ post.user_id }">{ post.user.name }</a><span class="username">@{ post.user.username }</span></div>
|
||||||
header
|
<div class="right"><a class="time" href="{ url }">
|
||||||
div.left
|
<mk-time time="{ post.created_at }"></mk-time></a></div>
|
||||||
a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id })
|
</header>
|
||||||
| { post.user.name }
|
<div class="body">
|
||||||
span.username
|
<div class="text" ref="text"></div>
|
||||||
| @{ post.user.username }
|
<div class="media" if="{ post.media }">
|
||||||
div.right
|
<virtual each="{ file in post.media }"><img src="{ file.url + '?thumbnail&size=512' }" alt="{ file.name }" title="{ file.name }"/></virtual>
|
||||||
a.time(href={ url })
|
</div>
|
||||||
mk-time(time={ post.created_at })
|
</div>
|
||||||
div.body
|
</div>
|
||||||
div.text@text
|
<style type="stylus">
|
||||||
div.media(if={ post.media })
|
:scope
|
||||||
virtual(each={ file in post.media })
|
|
||||||
img(src={ file.url + '?thumbnail&size=512' }, alt={ file.name }, title={ file.name })
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 20px 32px
|
|
||||||
background #fdfdfd
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
> .main > footer > button
|
|
||||||
color #888
|
|
||||||
|
|
||||||
> .avatar-anchor
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
margin 0 16px 0 0
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
display block
|
||||||
width 44px
|
|
||||||
height 44px
|
|
||||||
margin 0
|
margin 0
|
||||||
border-radius 4px
|
padding 20px 32px
|
||||||
vertical-align bottom
|
background #fdfdfd
|
||||||
|
|
||||||
> .main
|
|
||||||
float left
|
|
||||||
width calc(100% - 60px)
|
|
||||||
|
|
||||||
> header
|
|
||||||
margin-bottom 4px
|
|
||||||
white-space nowrap
|
|
||||||
|
|
||||||
&:after
|
&:after
|
||||||
content ""
|
content ""
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .left
|
&:hover
|
||||||
float left
|
> .main > footer > button
|
||||||
|
color #888
|
||||||
|
|
||||||
> .name
|
> .avatar-anchor
|
||||||
display inline
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
color #777
|
|
||||||
font-size 1em
|
|
||||||
font-weight 700
|
|
||||||
text-align left
|
|
||||||
text-decoration none
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
> .username
|
|
||||||
text-align left
|
|
||||||
margin 0 0 0 8px
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
> .right
|
|
||||||
float right
|
|
||||||
|
|
||||||
> .time
|
|
||||||
font-size 0.9em
|
|
||||||
color #c0c0c0
|
|
||||||
|
|
||||||
> .body
|
|
||||||
|
|
||||||
> .text
|
|
||||||
cursor default
|
|
||||||
display block
|
display block
|
||||||
margin 0
|
float left
|
||||||
padding 0
|
margin 0 16px 0 0
|
||||||
word-wrap break-word
|
|
||||||
font-size 1em
|
|
||||||
color #717171
|
|
||||||
|
|
||||||
> mk-url-preview
|
> .avatar
|
||||||
margin-top 8px
|
|
||||||
|
|
||||||
> .media
|
|
||||||
> img
|
|
||||||
display block
|
display block
|
||||||
max-width 100%
|
width 44px
|
||||||
|
height 44px
|
||||||
|
margin 0
|
||||||
|
border-radius 4px
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
script.
|
> .main
|
||||||
@mixin \api
|
float left
|
||||||
@mixin \text
|
width calc(100% - 60px)
|
||||||
@mixin \date-stringify
|
|
||||||
@mixin \user-preview
|
|
||||||
|
|
||||||
@post = @opts.post
|
> header
|
||||||
|
margin-bottom 4px
|
||||||
|
white-space nowrap
|
||||||
|
|
||||||
@url = CONFIG.url + '/' + @post.user.username + '/' + @post.id
|
&:after
|
||||||
|
content ""
|
||||||
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
@title = @date-stringify @post.created_at
|
> .left
|
||||||
|
float left
|
||||||
|
|
||||||
@on \mount ~>
|
> .name
|
||||||
if @post.text?
|
display inline
|
||||||
tokens = @analyze @post.text
|
margin 0
|
||||||
@refs.text.innerHTML = @compile tokens
|
padding 0
|
||||||
|
color #777
|
||||||
|
font-size 1em
|
||||||
|
font-weight 700
|
||||||
|
text-align left
|
||||||
|
text-decoration none
|
||||||
|
|
||||||
@refs.text.children.for-each (e) ~>
|
&:hover
|
||||||
if e.tag-name == \MK-URL
|
text-decoration underline
|
||||||
riot.mount e
|
|
||||||
|
|
||||||
@like = ~>
|
> .username
|
||||||
if @post.is_liked
|
text-align left
|
||||||
@api \posts/likes/delete do
|
margin 0 0 0 8px
|
||||||
post_id: @post.id
|
color #ccc
|
||||||
.then ~>
|
|
||||||
@post.is_liked = false
|
> .right
|
||||||
@update!
|
float right
|
||||||
else
|
|
||||||
@api \posts/likes/create do
|
> .time
|
||||||
post_id: @post.id
|
font-size 0.9em
|
||||||
.then ~>
|
color #c0c0c0
|
||||||
@post.is_liked = true
|
|
||||||
@update!
|
> .body
|
||||||
|
|
||||||
|
> .text
|
||||||
|
cursor default
|
||||||
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
word-wrap break-word
|
||||||
|
font-size 1em
|
||||||
|
color #717171
|
||||||
|
|
||||||
|
> mk-url-preview
|
||||||
|
margin-top 8px
|
||||||
|
|
||||||
|
> .media
|
||||||
|
> img
|
||||||
|
display block
|
||||||
|
max-width 100%
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \text
|
||||||
|
@mixin \date-stringify
|
||||||
|
@mixin \user-preview
|
||||||
|
|
||||||
|
@post = @opts.post
|
||||||
|
|
||||||
|
@url = CONFIG.url + '/' + @post.user.username + '/' + @post.id
|
||||||
|
|
||||||
|
@title = @date-stringify @post.created_at
|
||||||
|
|
||||||
|
@on \mount ~>
|
||||||
|
if @post.text?
|
||||||
|
tokens = @analyze @post.text
|
||||||
|
@refs.text.innerHTML = @compile tokens
|
||||||
|
|
||||||
|
@refs.text.children.for-each (e) ~>
|
||||||
|
if e.tag-name == \MK-URL
|
||||||
|
riot.mount e
|
||||||
|
|
||||||
|
@like = ~>
|
||||||
|
if @post.is_liked
|
||||||
|
@api \posts/likes/delete do
|
||||||
|
post_id: @post.id
|
||||||
|
.then ~>
|
||||||
|
@post.is_liked = false
|
||||||
|
@update!
|
||||||
|
else
|
||||||
|
@api \posts/likes/create do
|
||||||
|
post_id: @post.id
|
||||||
|
.then ~>
|
||||||
|
@post.is_liked = true
|
||||||
|
@update!
|
||||||
|
</script>
|
||||||
|
</mk-post-detail-sub>
|
||||||
|
|
|
@ -1,415 +1,409 @@
|
||||||
mk-post-detail(title={ title })
|
<mk-post-detail title="{ title }">
|
||||||
|
<div class="fetching" if="{ fetching }">
|
||||||
div.fetching(if={ fetching })
|
<mk-ellipsis-icon></mk-ellipsis-icon>
|
||||||
mk-ellipsis-icon
|
</div>
|
||||||
|
<div class="main" if="{ !fetching }">
|
||||||
div.main(if={ !fetching })
|
<button class="read-more" if="{ p.reply_to && p.reply_to.reply_to_id && context == null }" title="会話をもっと読み込む" onclick="{ loadContext }" disabled="{ loadingContext }"><i class="fa fa-ellipsis-v" if="{ !loadingContext }"></i><i class="fa fa-spinner fa-pulse" if="{ loadingContext }"></i></button>
|
||||||
|
<div class="context">
|
||||||
button.read-more(if={ p.reply_to && p.reply_to.reply_to_id && context == null }, title='会話をもっと読み込む', onclick={ load-context }, disabled={ loading-context })
|
<virtual each="{ post in context }">
|
||||||
i.fa.fa-ellipsis-v(if={ !loading-context })
|
<mk-post-detail-sub post="{ post }"></mk-post-detail-sub>
|
||||||
i.fa.fa-spinner.fa-pulse(if={ loading-context })
|
</virtual>
|
||||||
|
</div>
|
||||||
div.context
|
<div class="reply-to" if="{ p.reply_to }">
|
||||||
virtual(each={ post in context })
|
<mk-post-detail-sub post="{ p.reply_to }"></mk-post-detail-sub>
|
||||||
mk-post-detail-sub(post={ post })
|
</div>
|
||||||
|
<div class="repost" if="{ isRepost }">
|
||||||
div.reply-to(if={ p.reply_to })
|
<p><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }" data-user-preview="{ post.user_id }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&size=32' }" alt="avatar"/></a><i class="fa fa-retweet"></i><a class="name" href="{ CONFIG.url + '/' + post.user.username }">{ post.user.name }</a>がRepost</p>
|
||||||
mk-post-detail-sub(post={ p.reply_to })
|
</div>
|
||||||
|
<article><a class="avatar-anchor" href="{ CONFIG.url + '/' + p.user.username }"><img class="avatar" src="{ p.user.avatar_url + '?thumbnail&size=64' }" alt="avatar" data-user-preview="{ p.user.id }"/></a>
|
||||||
div.repost(if={ is-repost })
|
<header><a class="name" href="{ CONFIG.url + '/' + p.user.username }" data-user-preview="{ p.user.id }">{ p.user.name }</a><span class="username">@{ p.user.username }</span><a class="time" href="{ url }">
|
||||||
p
|
<mk-time time="{ p.created_at }"></mk-time></a></header>
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id }): img.avatar(src={ post.user.avatar_url + '?thumbnail&size=32' }, alt='avatar')
|
<div class="body">
|
||||||
i.fa.fa-retweet
|
<div class="text" ref="text"></div>
|
||||||
a.name(href={ CONFIG.url + '/' + post.user.username }) { post.user.name }
|
<div class="media" if="{ p.media }">
|
||||||
| がRepost
|
<virtual each="{ file in p.media }"><img src="{ file.url + '?thumbnail&size=512' }" alt="{ file.name }" title="{ file.name }"/></virtual>
|
||||||
|
</div>
|
||||||
article
|
</div>
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + p.user.username })
|
<footer>
|
||||||
img.avatar(src={ p.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ p.user.id })
|
<button onclick="{ reply }" title="返信"><i class="fa fa-reply"></i>
|
||||||
header
|
<p class="count" if="{ p.replies_count > 0 }">{ p.replies_count }</p>
|
||||||
a.name(href={ CONFIG.url + '/' + p.user.username }, data-user-preview={ p.user.id })
|
</button>
|
||||||
| { p.user.name }
|
<button onclick="{ repost }" title="Repost"><i class="fa fa-retweet"></i>
|
||||||
span.username
|
<p class="count" if="{ p.repost_count > 0 }">{ p.repost_count }</p>
|
||||||
| @{ p.user.username }
|
</button>
|
||||||
a.time(href={ url })
|
<button class="{ liked: p.is_liked }" onclick="{ like }" title="善哉"><i class="fa fa-thumbs-o-up"></i>
|
||||||
mk-time(time={ p.created_at })
|
<p class="count" if="{ p.likes_count > 0 }">{ p.likes_count }</p>
|
||||||
div.body
|
</button>
|
||||||
div.text@text
|
<button onclick="{ NotImplementedException }"><i class="fa fa-ellipsis-h"></i></button>
|
||||||
div.media(if={ p.media })
|
</footer>
|
||||||
virtual(each={ file in p.media })
|
<div class="reposts-and-likes">
|
||||||
img(src={ file.url + '?thumbnail&size=512' }, alt={ file.name }, title={ file.name })
|
<div class="reposts" if="{ reposts && reposts.length > 0 }">
|
||||||
footer
|
<header><a>{ p.repost_count }</a>
|
||||||
button(onclick={ reply }, title='返信')
|
<p>Repost</p>
|
||||||
i.fa.fa-reply
|
</header>
|
||||||
p.count(if={ p.replies_count > 0 }) { p.replies_count }
|
<ol class="users">
|
||||||
button(onclick={ repost }, title='Repost')
|
<li class="user" each="{ reposts }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + user.username }" title="{ user.name }" data-user-preview="{ user.id }"><img class="avatar" src="{ user.avatar_url + '?thumbnail&size=32' }" alt=""/></a></li>
|
||||||
i.fa.fa-retweet
|
</ol>
|
||||||
p.count(if={ p.repost_count > 0 }) { p.repost_count }
|
</div>
|
||||||
button(class={ liked: p.is_liked }, onclick={ like }, title='善哉')
|
<div class="likes" if="{ likes && likes.length > 0 }">
|
||||||
i.fa.fa-thumbs-o-up
|
<header><a>{ p.likes_count }</a>
|
||||||
p.count(if={ p.likes_count > 0 }) { p.likes_count }
|
<p>いいね</p>
|
||||||
button(onclick={ NotImplementedException }): i.fa.fa-ellipsis-h
|
</header>
|
||||||
div.reposts-and-likes
|
<ol class="users">
|
||||||
div.reposts(if={ reposts && reposts.length > 0 })
|
<li class="user" each="{ likes }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + username }" title="{ name }" data-user-preview="{ id }"><img class="avatar" src="{ avatar_url + '?thumbnail&size=32' }" alt=""/></a></li>
|
||||||
header
|
</ol>
|
||||||
a { p.repost_count }
|
</div>
|
||||||
p Repost
|
</div>
|
||||||
ol.users
|
</article>
|
||||||
li.user(each={ reposts })
|
<div class="replies">
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + user.username }, title={ user.name }, data-user-preview={ user.id })
|
<virtual each="{ post in replies }">
|
||||||
img.avatar(src={ user.avatar_url + '?thumbnail&size=32' }, alt='')
|
<mk-post-detail-sub post="{ post }"></mk-post-detail-sub>
|
||||||
div.likes(if={ likes && likes.length > 0 })
|
</virtual>
|
||||||
header
|
</div>
|
||||||
a { p.likes_count }
|
</div>
|
||||||
p いいね
|
<style type="stylus">
|
||||||
ol.users
|
:scope
|
||||||
li.user(each={ likes })
|
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + username }, title={ name }, data-user-preview={ id })
|
|
||||||
img.avatar(src={ avatar_url + '?thumbnail&size=32' }, alt='')
|
|
||||||
|
|
||||||
div.replies
|
|
||||||
virtual(each={ post in replies })
|
|
||||||
mk-post-detail-sub(post={ post })
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
width 640px
|
|
||||||
overflow hidden
|
|
||||||
background #fff
|
|
||||||
border solid 1px rgba(0, 0, 0, 0.1)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
> .fetching
|
|
||||||
padding 64px 0
|
|
||||||
|
|
||||||
> .main
|
|
||||||
|
|
||||||
> .read-more
|
|
||||||
display block
|
display block
|
||||||
margin 0
|
margin 0
|
||||||
padding 10px 0
|
padding 0
|
||||||
width 100%
|
width 640px
|
||||||
font-size 1em
|
overflow hidden
|
||||||
text-align center
|
background #fff
|
||||||
color #999
|
border solid 1px rgba(0, 0, 0, 0.1)
|
||||||
cursor pointer
|
border-radius 8px
|
||||||
background #fafafa
|
|
||||||
outline none
|
|
||||||
border none
|
|
||||||
border-bottom solid 1px #eef0f2
|
|
||||||
border-radius 6px 6px 0 0
|
|
||||||
|
|
||||||
&:hover
|
> .fetching
|
||||||
background #f6f6f6
|
padding 64px 0
|
||||||
|
|
||||||
&:active
|
> .main
|
||||||
background #f0f0f0
|
|
||||||
|
|
||||||
&:disabled
|
> .read-more
|
||||||
color #ccc
|
|
||||||
|
|
||||||
> .context
|
|
||||||
> *
|
|
||||||
border-bottom 1px solid #eef0f2
|
|
||||||
|
|
||||||
> .repost
|
|
||||||
color #9dbb00
|
|
||||||
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
|
|
||||||
|
|
||||||
> p
|
|
||||||
margin 0
|
|
||||||
padding 16px 32px
|
|
||||||
|
|
||||||
.avatar-anchor
|
|
||||||
display inline-block
|
|
||||||
|
|
||||||
.avatar
|
|
||||||
vertical-align bottom
|
|
||||||
min-width 28px
|
|
||||||
min-height 28px
|
|
||||||
max-width 28px
|
|
||||||
max-height 28px
|
|
||||||
margin 0 8px 0 0
|
|
||||||
border-radius 6px
|
|
||||||
|
|
||||||
i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
.name
|
|
||||||
font-weight bold
|
|
||||||
|
|
||||||
& + article
|
|
||||||
padding-top 8px
|
|
||||||
|
|
||||||
> .reply-to
|
|
||||||
border-bottom 1px solid #eef0f2
|
|
||||||
|
|
||||||
> article
|
|
||||||
padding 28px 32px 18px 32px
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
> .main > footer > button
|
|
||||||
color #888
|
|
||||||
|
|
||||||
> .avatar-anchor
|
|
||||||
display block
|
|
||||||
width 60px
|
|
||||||
height 60px
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
display block
|
||||||
width 60px
|
|
||||||
height 60px
|
|
||||||
margin 0
|
margin 0
|
||||||
border-radius 8px
|
padding 10px 0
|
||||||
vertical-align bottom
|
width 100%
|
||||||
|
|
||||||
> header
|
|
||||||
position absolute
|
|
||||||
top 28px
|
|
||||||
left 108px
|
|
||||||
width calc(100% - 108px)
|
|
||||||
|
|
||||||
> .name
|
|
||||||
display inline-block
|
|
||||||
margin 0
|
|
||||||
line-height 24px
|
|
||||||
color #777
|
|
||||||
font-size 18px
|
|
||||||
font-weight 700
|
|
||||||
text-align left
|
|
||||||
text-decoration none
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
> .username
|
|
||||||
display block
|
|
||||||
text-align left
|
|
||||||
margin 0
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
> .time
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
right 32px
|
|
||||||
font-size 1em
|
font-size 1em
|
||||||
color #c0c0c0
|
text-align center
|
||||||
|
color #999
|
||||||
> .body
|
|
||||||
padding 8px 0
|
|
||||||
|
|
||||||
> .text
|
|
||||||
cursor default
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
word-wrap break-word
|
|
||||||
font-size 1.5em
|
|
||||||
color #717171
|
|
||||||
|
|
||||||
> mk-url-preview
|
|
||||||
margin-top 8px
|
|
||||||
|
|
||||||
> .media
|
|
||||||
> img
|
|
||||||
display block
|
|
||||||
max-width 100%
|
|
||||||
|
|
||||||
> footer
|
|
||||||
font-size 1.2em
|
|
||||||
|
|
||||||
> button
|
|
||||||
margin 0 28px 0 0
|
|
||||||
padding 8px
|
|
||||||
background transparent
|
|
||||||
border none
|
|
||||||
font-size 1em
|
|
||||||
color #ddd
|
|
||||||
cursor pointer
|
cursor pointer
|
||||||
|
background #fafafa
|
||||||
|
outline none
|
||||||
|
border none
|
||||||
|
border-bottom solid 1px #eef0f2
|
||||||
|
border-radius 6px 6px 0 0
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
color #666
|
background #f6f6f6
|
||||||
|
|
||||||
> .count
|
&:active
|
||||||
display inline
|
background #f0f0f0
|
||||||
margin 0 0 0 8px
|
|
||||||
color #999
|
|
||||||
|
|
||||||
&.liked
|
&:disabled
|
||||||
color $theme-color
|
color #ccc
|
||||||
|
|
||||||
> .reposts-and-likes
|
> .context
|
||||||
display flex
|
> *
|
||||||
justify-content center
|
border-bottom 1px solid #eef0f2
|
||||||
padding 0
|
|
||||||
margin 16px 0
|
|
||||||
|
|
||||||
&:empty
|
> .repost
|
||||||
display none
|
color #9dbb00
|
||||||
|
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
|
||||||
|
|
||||||
> .reposts
|
> p
|
||||||
> .likes
|
margin 0
|
||||||
display flex
|
padding 16px 32px
|
||||||
flex 1 1
|
|
||||||
padding 0
|
.avatar-anchor
|
||||||
border-top solid 1px #F2EFEE
|
display inline-block
|
||||||
|
|
||||||
|
.avatar
|
||||||
|
vertical-align bottom
|
||||||
|
min-width 28px
|
||||||
|
min-height 28px
|
||||||
|
max-width 28px
|
||||||
|
max-height 28px
|
||||||
|
margin 0 8px 0 0
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
|
.name
|
||||||
|
font-weight bold
|
||||||
|
|
||||||
|
& + article
|
||||||
|
padding-top 8px
|
||||||
|
|
||||||
|
> .reply-to
|
||||||
|
border-bottom 1px solid #eef0f2
|
||||||
|
|
||||||
|
> article
|
||||||
|
padding 28px 32px 18px 32px
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ""
|
||||||
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
> .main > footer > button
|
||||||
|
color #888
|
||||||
|
|
||||||
|
> .avatar-anchor
|
||||||
|
display block
|
||||||
|
width 60px
|
||||||
|
height 60px
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
display block
|
||||||
|
width 60px
|
||||||
|
height 60px
|
||||||
|
margin 0
|
||||||
|
border-radius 8px
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
> header
|
> header
|
||||||
flex 1 1 80px
|
position absolute
|
||||||
max-width 80px
|
top 28px
|
||||||
padding 8px 5px 0px 10px
|
left 108px
|
||||||
|
width calc(100% - 108px)
|
||||||
|
|
||||||
> a
|
> .name
|
||||||
|
display inline-block
|
||||||
|
margin 0
|
||||||
|
line-height 24px
|
||||||
|
color #777
|
||||||
|
font-size 18px
|
||||||
|
font-weight 700
|
||||||
|
text-align left
|
||||||
|
text-decoration none
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
text-decoration underline
|
||||||
|
|
||||||
|
> .username
|
||||||
display block
|
display block
|
||||||
font-size 1.5em
|
text-align left
|
||||||
line-height 1.4em
|
margin 0
|
||||||
|
color #ccc
|
||||||
|
|
||||||
> p
|
> .time
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
right 32px
|
||||||
|
font-size 1em
|
||||||
|
color #c0c0c0
|
||||||
|
|
||||||
|
> .body
|
||||||
|
padding 8px 0
|
||||||
|
|
||||||
|
> .text
|
||||||
|
cursor default
|
||||||
display block
|
display block
|
||||||
margin 0
|
margin 0
|
||||||
font-size 0.7em
|
|
||||||
line-height 1em
|
|
||||||
font-weight normal
|
|
||||||
color #a0a2a5
|
|
||||||
|
|
||||||
> .users
|
|
||||||
display block
|
|
||||||
flex 1 1
|
|
||||||
margin 0
|
|
||||||
padding 10px 10px 10px 5px
|
|
||||||
list-style none
|
|
||||||
|
|
||||||
> .user
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
margin 4px
|
|
||||||
padding 0
|
padding 0
|
||||||
|
word-wrap break-word
|
||||||
|
font-size 1.5em
|
||||||
|
color #717171
|
||||||
|
|
||||||
> .avatar-anchor
|
> mk-url-preview
|
||||||
display:block
|
margin-top 8px
|
||||||
|
|
||||||
> .avatar
|
> .media
|
||||||
vertical-align bottom
|
> img
|
||||||
width 24px
|
display block
|
||||||
height 24px
|
max-width 100%
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
> .reposts + .likes
|
> footer
|
||||||
margin-left 16px
|
font-size 1.2em
|
||||||
|
|
||||||
> .replies
|
> button
|
||||||
> *
|
margin 0 28px 0 0
|
||||||
border-top 1px solid #eef0f2
|
padding 8px
|
||||||
|
background transparent
|
||||||
|
border none
|
||||||
|
font-size 1em
|
||||||
|
color #ddd
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
script.
|
&:hover
|
||||||
@mixin \api
|
color #666
|
||||||
@mixin \text
|
|
||||||
@mixin \user-preview
|
|
||||||
@mixin \date-stringify
|
|
||||||
@mixin \NotImplementedException
|
|
||||||
|
|
||||||
@fetching = true
|
> .count
|
||||||
@loading-context = false
|
display inline
|
||||||
@content = null
|
margin 0 0 0 8px
|
||||||
@post = null
|
color #999
|
||||||
|
|
||||||
@on \mount ~>
|
&.liked
|
||||||
|
color $theme-color
|
||||||
|
|
||||||
@api \posts/show do
|
> .reposts-and-likes
|
||||||
post_id: @opts.post
|
display flex
|
||||||
.then (post) ~>
|
justify-content center
|
||||||
@fetching = false
|
padding 0
|
||||||
@post = post
|
margin 16px 0
|
||||||
@trigger \loaded
|
|
||||||
|
|
||||||
@is-repost = @post.repost?
|
&:empty
|
||||||
@p = if @is-repost then @post.repost else @post
|
display none
|
||||||
|
|
||||||
@title = @date-stringify @p.created_at
|
> .reposts
|
||||||
|
> .likes
|
||||||
|
display flex
|
||||||
|
flex 1 1
|
||||||
|
padding 0
|
||||||
|
border-top solid 1px #F2EFEE
|
||||||
|
|
||||||
@update!
|
> header
|
||||||
|
flex 1 1 80px
|
||||||
|
max-width 80px
|
||||||
|
padding 8px 5px 0px 10px
|
||||||
|
|
||||||
if @p.text?
|
> a
|
||||||
tokens = @analyze @p.text
|
display block
|
||||||
@refs.text.innerHTML = @compile tokens
|
font-size 1.5em
|
||||||
|
line-height 1.4em
|
||||||
|
|
||||||
@refs.text.children.for-each (e) ~>
|
> p
|
||||||
if e.tag-name == \MK-URL
|
display block
|
||||||
riot.mount e
|
margin 0
|
||||||
|
font-size 0.7em
|
||||||
|
line-height 1em
|
||||||
|
font-weight normal
|
||||||
|
color #a0a2a5
|
||||||
|
|
||||||
# URLをプレビュー
|
> .users
|
||||||
tokens
|
display block
|
||||||
.filter (t) -> t.type == \link
|
flex 1 1
|
||||||
.map (t) ~>
|
margin 0
|
||||||
@preview = @refs.text.append-child document.create-element \mk-url-preview
|
padding 10px 10px 10px 5px
|
||||||
riot.mount @preview, do
|
list-style none
|
||||||
url: t.content
|
|
||||||
|
> .user
|
||||||
|
display block
|
||||||
|
float left
|
||||||
|
margin 4px
|
||||||
|
padding 0
|
||||||
|
|
||||||
|
> .avatar-anchor
|
||||||
|
display:block
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
vertical-align bottom
|
||||||
|
width 24px
|
||||||
|
height 24px
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
|
> .reposts + .likes
|
||||||
|
margin-left 16px
|
||||||
|
|
||||||
|
> .replies
|
||||||
|
> *
|
||||||
|
border-top 1px solid #eef0f2
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \text
|
||||||
|
@mixin \user-preview
|
||||||
|
@mixin \date-stringify
|
||||||
|
@mixin \NotImplementedException
|
||||||
|
|
||||||
|
@fetching = true
|
||||||
|
@loading-context = false
|
||||||
|
@content = null
|
||||||
|
@post = null
|
||||||
|
|
||||||
|
@on \mount ~>
|
||||||
|
|
||||||
|
@api \posts/show do
|
||||||
|
post_id: @opts.post
|
||||||
|
.then (post) ~>
|
||||||
|
@fetching = false
|
||||||
|
@post = post
|
||||||
|
@trigger \loaded
|
||||||
|
|
||||||
|
@is-repost = @post.repost?
|
||||||
|
@p = if @is-repost then @post.repost else @post
|
||||||
|
|
||||||
|
@title = @date-stringify @p.created_at
|
||||||
|
|
||||||
# Get likes
|
|
||||||
@api \posts/likes do
|
|
||||||
post_id: @p.id
|
|
||||||
limit: 8
|
|
||||||
.then (likes) ~>
|
|
||||||
@likes = likes
|
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
# Get reposts
|
if @p.text?
|
||||||
@api \posts/reposts do
|
tokens = @analyze @p.text
|
||||||
post_id: @p.id
|
@refs.text.innerHTML = @compile tokens
|
||||||
limit: 8
|
|
||||||
.then (reposts) ~>
|
@refs.text.children.for-each (e) ~>
|
||||||
@reposts = reposts
|
if e.tag-name == \MK-URL
|
||||||
|
riot.mount e
|
||||||
|
|
||||||
|
# URLをプレビュー
|
||||||
|
tokens
|
||||||
|
.filter (t) -> t.type == \link
|
||||||
|
.map (t) ~>
|
||||||
|
@preview = @refs.text.append-child document.create-element \mk-url-preview
|
||||||
|
riot.mount @preview, do
|
||||||
|
url: t.content
|
||||||
|
|
||||||
|
# Get likes
|
||||||
|
@api \posts/likes do
|
||||||
|
post_id: @p.id
|
||||||
|
limit: 8
|
||||||
|
.then (likes) ~>
|
||||||
|
@likes = likes
|
||||||
|
@update!
|
||||||
|
|
||||||
|
# Get reposts
|
||||||
|
@api \posts/reposts do
|
||||||
|
post_id: @p.id
|
||||||
|
limit: 8
|
||||||
|
.then (reposts) ~>
|
||||||
|
@reposts = reposts
|
||||||
|
@update!
|
||||||
|
|
||||||
|
# Get replies
|
||||||
|
@api \posts/replies do
|
||||||
|
post_id: @p.id
|
||||||
|
limit: 8
|
||||||
|
.then (replies) ~>
|
||||||
|
@replies = replies
|
||||||
|
@update!
|
||||||
|
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
# Get replies
|
@reply = ~>
|
||||||
@api \posts/replies do
|
form = document.body.append-child document.create-element \mk-post-form-window
|
||||||
post_id: @p.id
|
riot.mount form, do
|
||||||
limit: 8
|
reply: @p
|
||||||
.then (replies) ~>
|
|
||||||
@replies = replies
|
@repost = ~>
|
||||||
|
form = document.body.append-child document.create-element \mk-repost-form-window
|
||||||
|
riot.mount form, do
|
||||||
|
post: @p
|
||||||
|
|
||||||
|
@like = ~>
|
||||||
|
if @p.is_liked
|
||||||
|
@api \posts/likes/delete do
|
||||||
|
post_id: @p.id
|
||||||
|
.then ~>
|
||||||
|
@p.is_liked = false
|
||||||
|
@update!
|
||||||
|
else
|
||||||
|
@api \posts/likes/create do
|
||||||
|
post_id: @p.id
|
||||||
|
.then ~>
|
||||||
|
@p.is_liked = true
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@load-context = ~>
|
||||||
|
@loading-context = true
|
||||||
|
|
||||||
|
# Get context
|
||||||
|
@api \posts/context do
|
||||||
|
post_id: @p.reply_to_id
|
||||||
|
.then (context) ~>
|
||||||
|
@context = context.reverse!
|
||||||
|
@loading-context = false
|
||||||
@update!
|
@update!
|
||||||
|
</script>
|
||||||
@update!
|
</mk-post-detail>
|
||||||
|
|
||||||
@reply = ~>
|
|
||||||
form = document.body.append-child document.create-element \mk-post-form-window
|
|
||||||
riot.mount form, do
|
|
||||||
reply: @p
|
|
||||||
|
|
||||||
@repost = ~>
|
|
||||||
form = document.body.append-child document.create-element \mk-repost-form-window
|
|
||||||
riot.mount form, do
|
|
||||||
post: @p
|
|
||||||
|
|
||||||
@like = ~>
|
|
||||||
if @p.is_liked
|
|
||||||
@api \posts/likes/delete do
|
|
||||||
post_id: @p.id
|
|
||||||
.then ~>
|
|
||||||
@p.is_liked = false
|
|
||||||
@update!
|
|
||||||
else
|
|
||||||
@api \posts/likes/create do
|
|
||||||
post_id: @p.id
|
|
||||||
.then ~>
|
|
||||||
@p.is_liked = true
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@load-context = ~>
|
|
||||||
@loading-context = true
|
|
||||||
|
|
||||||
# Get context
|
|
||||||
@api \posts/context do
|
|
||||||
post_id: @p.reply_to_id
|
|
||||||
.then (context) ~>
|
|
||||||
@context = context.reverse!
|
|
||||||
@loading-context = false
|
|
||||||
@update!
|
|
||||||
|
|
|
@ -1,60 +1,55 @@
|
||||||
mk-post-form-window
|
<mk-post-form-window>
|
||||||
|
<mk-window ref="window" is-modal="{ true }" colored="{ true }"><yield to="header"><span if="{ !parent.opts.reply }">新規投稿</span><span if="{ parent.opts.reply }">返信</span><span class="files" if="{ parent.files.length != 0 }">添付: { parent.files.length }ファイル</span><span class="uploading-files" if="{ parent.uploadingFiles.length != 0 }">{ parent.uploadingFiles.length }個のファイルをアップロード中
|
||||||
|
<mk-ellipsis></mk-ellipsis></span></yield>
|
||||||
|
<yield to="content">
|
||||||
|
<div class="ref" if="{ parent.opts.reply }">
|
||||||
|
<mk-post-preview post="{ parent.opts.reply }"></mk-post-preview>
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
|
<mk-post-form ref="form" reply="{ parent.opts.reply }"></mk-post-form>
|
||||||
|
</div></yield>
|
||||||
|
</mk-window>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
> mk-window
|
||||||
|
|
||||||
mk-window@window(is-modal={ true }, colored={ true })
|
[data-yield='header']
|
||||||
|
> .files
|
||||||
|
> .uploading-files
|
||||||
|
margin-left 8px
|
||||||
|
opacity 0.8
|
||||||
|
|
||||||
<yield to="header">
|
&:before
|
||||||
span(if={ !parent.opts.reply }) 新規投稿
|
content '('
|
||||||
span(if={ parent.opts.reply }) 返信
|
|
||||||
span.files(if={ parent.files.length != 0 }) 添付: { parent.files.length }ファイル
|
|
||||||
span.uploading-files(if={ parent.uploading-files.length != 0 })
|
|
||||||
| { parent.uploading-files.length }個のファイルをアップロード中
|
|
||||||
mk-ellipsis
|
|
||||||
</yield>
|
|
||||||
|
|
||||||
<yield to="content">
|
&:after
|
||||||
div.ref(if={ parent.opts.reply })
|
content ')'
|
||||||
mk-post-preview(post={ parent.opts.reply })
|
|
||||||
div.body
|
|
||||||
mk-post-form@form(reply={ parent.opts.reply })
|
|
||||||
</yield>
|
|
||||||
|
|
||||||
style.
|
[data-yield='content']
|
||||||
> mk-window
|
> .ref
|
||||||
|
> mk-post-preview
|
||||||
|
margin 16px 22px
|
||||||
|
|
||||||
[data-yield='header']
|
</style>
|
||||||
> .files
|
<script>
|
||||||
> .uploading-files
|
@uploading-files = []
|
||||||
margin-left 8px
|
@files = []
|
||||||
opacity 0.8
|
|
||||||
|
|
||||||
&:before
|
@on \mount ~>
|
||||||
content '('
|
@refs.window.refs.form.focus!
|
||||||
|
|
||||||
&:after
|
@refs.window.on \closed ~>
|
||||||
content ')'
|
@unmount!
|
||||||
|
|
||||||
[data-yield='content']
|
@refs.window.refs.form.on \post ~>
|
||||||
> .ref
|
@refs.window.close!
|
||||||
> mk-post-preview
|
|
||||||
margin 16px 22px
|
|
||||||
|
|
||||||
script.
|
@refs.window.refs.form.on \change-uploading-files (files) ~>
|
||||||
@uploading-files = []
|
@uploading-files = files
|
||||||
@files = []
|
@update!
|
||||||
|
|
||||||
@on \mount ~>
|
@refs.window.refs.form.on \change-files (files) ~>
|
||||||
@refs.window.refs.form.focus!
|
@files = files
|
||||||
|
@update!
|
||||||
@refs.window.on \closed ~>
|
</script>
|
||||||
@unmount!
|
</mk-post-form-window>
|
||||||
|
|
||||||
@refs.window.refs.form.on \post ~>
|
|
||||||
@refs.window.close!
|
|
||||||
|
|
||||||
@refs.window.refs.form.on \change-uploading-files (files) ~>
|
|
||||||
@uploading-files = files
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@refs.window.refs.form.on \change-files (files) ~>
|
|
||||||
@files = files
|
|
||||||
@update!
|
|
||||||
|
|
|
@ -1,430 +1,434 @@
|
||||||
mk-post-form(ondragover={ ondragover }, ondragenter={ ondragenter }, ondragleave={ ondragleave }, ondrop={ ondrop })
|
<mk-post-form ondragover="{ ondragover }" ondragenter="{ ondragenter }" ondragleave="{ ondragleave }" ondrop="{ ondrop }">
|
||||||
textarea@text(disabled={ wait }, class={ withfiles: files.length != 0 }, oninput={ update }, onkeydown={ onkeydown }, onpaste={ onpaste }, placeholder={ opts.reply ? 'この投稿への返信...' : 'いまどうしてる?' })
|
<textarea class="{ withfiles: files.length != 0 }" ref="text" disabled="{ wait }" oninput="{ update }" onkeydown="{ onkeydown }" onpaste="{ onpaste }" placeholder="{ opts.reply ? 'この投稿への返信...' : 'いまどうしてる?' }"></textarea>
|
||||||
div.attaches(if={ files.length != 0 })
|
<div class="attaches" if="{ files.length != 0 }">
|
||||||
ul.files@attaches
|
<ul class="files" ref="attaches">
|
||||||
li.file(each={ files })
|
<li class="file" each="{ files }">
|
||||||
div.img(style='background-image: url({ url + "?thumbnail&size=64" })', title={ name })
|
<div class="img" style="background-image: url({ url + "?thumbnail&size=64" })" title="{ name }"></div><img class="remove" onclick="{ _remove }" src="/_/resources/desktop/remove.png" title="添付取り消し" alt=""/>
|
||||||
img.remove(onclick={ _remove }, src='/_/resources/desktop/remove.png', title='添付取り消し', alt='')
|
</li>
|
||||||
li.add(if={ files.length < 4 }, title='PCからファイルを添付', onclick={ select-file }): i.fa.fa-plus
|
<li class="add" if="{ files.length < 4 }" title="PCからファイルを添付" onclick="{ selectFile }"><i class="fa fa-plus"></i></li>
|
||||||
p.remain
|
</ul>
|
||||||
| 残り{ 4 - files.length }
|
<p class="remain">残り{ 4 - files.length }</p>
|
||||||
mk-uploader@uploader
|
</div>
|
||||||
button@upload(title='PCからファイルを添付', onclick={ select-file }): i.fa.fa-upload
|
<mk-uploader ref="uploader"></mk-uploader>
|
||||||
button@drive(title='ドライブからファイルを添付', onclick={ select-file-from-drive }): i.fa.fa-cloud
|
<button ref="upload" title="PCからファイルを添付" onclick="{ selectFile }"><i class="fa fa-upload"></i></button>
|
||||||
p.text-count(class={ over: refs.text.value.length > 300 }) のこり{ 300 - refs.text.value.length }文字
|
<button ref="drive" title="ドライブからファイルを添付" onclick="{ selectFileFromDrive }"><i class="fa fa-cloud"></i></button>
|
||||||
button@submit(class={ wait: wait }, disabled={ wait || (refs.text.value.length == 0 && files.length == 0) }, onclick={ post })
|
<p class="text-count { over: refs.text.value.length > 300 }">のこり{ 300 - refs.text.value.length }文字</p>
|
||||||
| { wait ? '投稿中' : opts.reply ? '返信' : '投稿' }
|
<button class="{ wait: wait }" ref="submit" disabled="{ wait || (refs.text.value.length == 0 && files.length == 0) }" onclick="{ post }">{ wait ? '投稿中' : opts.reply ? '返信' : '投稿' }
|
||||||
mk-ellipsis(if={ wait })
|
<mk-ellipsis if="{ wait }"></mk-ellipsis>
|
||||||
input@file(type='file', accept='image/*', multiple, tabindex='-1', onchange={ change-file })
|
</button>
|
||||||
div.dropzone(if={ draghover })
|
<input ref="file" type="file" accept="image/*" multiple="multiple" tabindex="-1" onchange="{ changeFile }"/>
|
||||||
|
<div class="dropzone" if="{ draghover }"></div>
|
||||||
style.
|
<style type="stylus">
|
||||||
display block
|
:scope
|
||||||
padding 16px
|
|
||||||
background lighten($theme-color, 95%)
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
> .attaches
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
background lighten($theme-color, 98%)
|
|
||||||
border solid 1px rgba($theme-color, 0.1)
|
|
||||||
border-top none
|
|
||||||
border-radius 0 0 4px 4px
|
|
||||||
transition border-color .3s ease
|
|
||||||
|
|
||||||
> .remain
|
|
||||||
display block
|
display block
|
||||||
position absolute
|
padding 16px
|
||||||
top 8px
|
background lighten($theme-color, 95%)
|
||||||
right 8px
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
color rgba($theme-color, 0.4)
|
|
||||||
|
|
||||||
> .files
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 4px
|
|
||||||
list-style none
|
|
||||||
|
|
||||||
&:after
|
&:after
|
||||||
content ""
|
content ""
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
> .file
|
> .attaches
|
||||||
display block
|
margin 0
|
||||||
float left
|
|
||||||
margin 4px
|
|
||||||
padding 0
|
padding 0
|
||||||
cursor move
|
background lighten($theme-color, 98%)
|
||||||
|
border solid 1px rgba($theme-color, 0.1)
|
||||||
|
border-top none
|
||||||
|
border-radius 0 0 4px 4px
|
||||||
|
transition border-color .3s ease
|
||||||
|
|
||||||
&:hover > .remove
|
> .remain
|
||||||
display block
|
display block
|
||||||
|
|
||||||
> .img
|
|
||||||
width 64px
|
|
||||||
height 64px
|
|
||||||
background-size cover
|
|
||||||
background-position center center
|
|
||||||
|
|
||||||
> .remove
|
|
||||||
display none
|
|
||||||
position absolute
|
position absolute
|
||||||
top -6px
|
top 8px
|
||||||
right -6px
|
right 8px
|
||||||
width 16px
|
margin 0
|
||||||
height 16px
|
padding 0
|
||||||
cursor pointer
|
color rgba($theme-color, 0.4)
|
||||||
|
|
||||||
> .add
|
> .files
|
||||||
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 4px
|
||||||
|
list-style none
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ""
|
||||||
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
|
> .file
|
||||||
|
display block
|
||||||
|
float left
|
||||||
|
margin 4px
|
||||||
|
padding 0
|
||||||
|
cursor move
|
||||||
|
|
||||||
|
&:hover > .remove
|
||||||
|
display block
|
||||||
|
|
||||||
|
> .img
|
||||||
|
width 64px
|
||||||
|
height 64px
|
||||||
|
background-size cover
|
||||||
|
background-position center center
|
||||||
|
|
||||||
|
> .remove
|
||||||
|
display none
|
||||||
|
position absolute
|
||||||
|
top -6px
|
||||||
|
right -6px
|
||||||
|
width 16px
|
||||||
|
height 16px
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
|
> .add
|
||||||
|
display block
|
||||||
|
float left
|
||||||
|
margin 4px
|
||||||
|
padding 0
|
||||||
|
border dashed 2px rgba($theme-color, 0.2)
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
border-color rgba($theme-color, 0.3)
|
||||||
|
|
||||||
|
> i
|
||||||
|
color rgba($theme-color, 0.4)
|
||||||
|
|
||||||
|
> i
|
||||||
|
display block
|
||||||
|
width 60px
|
||||||
|
height 60px
|
||||||
|
line-height 60px
|
||||||
|
text-align center
|
||||||
|
font-size 1.2em
|
||||||
|
color rgba($theme-color, 0.2)
|
||||||
|
|
||||||
|
> mk-uploader
|
||||||
|
margin 8px 0 0 0
|
||||||
|
padding 8px
|
||||||
|
border solid 1px rgba($theme-color, 0.2)
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
|
[ref='file']
|
||||||
|
display none
|
||||||
|
|
||||||
|
[ref='text']
|
||||||
display block
|
display block
|
||||||
float left
|
padding 12px
|
||||||
margin 4px
|
margin 0
|
||||||
padding 0
|
width 100%
|
||||||
border dashed 2px rgba($theme-color, 0.2)
|
max-width 100%
|
||||||
cursor pointer
|
min-width 100%
|
||||||
|
min-height calc(16px + 12px + 12px)
|
||||||
|
font-size 16px
|
||||||
|
color #333
|
||||||
|
background #fff
|
||||||
|
outline none
|
||||||
|
border solid 1px rgba($theme-color, 0.1)
|
||||||
|
border-radius 4px
|
||||||
|
transition border-color .3s ease
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
|
border-color rgba($theme-color, 0.2)
|
||||||
|
transition border-color .1s ease
|
||||||
|
|
||||||
|
&:focus
|
||||||
|
color $theme-color
|
||||||
|
border-color rgba($theme-color, 0.5)
|
||||||
|
transition border-color 0s ease
|
||||||
|
|
||||||
|
&:disabled
|
||||||
|
opacity 0.5
|
||||||
|
|
||||||
|
&::-webkit-input-placeholder
|
||||||
|
color rgba($theme-color, 0.3)
|
||||||
|
|
||||||
|
&.withfiles
|
||||||
|
border-bottom solid 1px rgba($theme-color, 0.1) !important
|
||||||
|
border-radius 4px 4px 0 0
|
||||||
|
|
||||||
|
&:hover + .attaches
|
||||||
|
border-color rgba($theme-color, 0.2)
|
||||||
|
transition border-color .1s ease
|
||||||
|
|
||||||
|
&:focus + .attaches
|
||||||
|
border-color rgba($theme-color, 0.5)
|
||||||
|
transition border-color 0s ease
|
||||||
|
|
||||||
|
.text-count
|
||||||
|
pointer-events none
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
bottom 16px
|
||||||
|
right 138px
|
||||||
|
margin 0
|
||||||
|
line-height 40px
|
||||||
|
color rgba($theme-color, 0.5)
|
||||||
|
|
||||||
|
&.over
|
||||||
|
color #ec3828
|
||||||
|
|
||||||
|
[ref='submit']
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
bottom 16px
|
||||||
|
right 16px
|
||||||
|
cursor pointer
|
||||||
|
padding 0
|
||||||
|
margin 0
|
||||||
|
width 110px
|
||||||
|
height 40px
|
||||||
|
font-size 1em
|
||||||
|
color $theme-color-foreground
|
||||||
|
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
||||||
|
outline none
|
||||||
|
border solid 1px lighten($theme-color, 15%)
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
|
&:not(:disabled)
|
||||||
|
font-weight bold
|
||||||
|
|
||||||
|
&:hover:not(:disabled)
|
||||||
|
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
||||||
|
border-color $theme-color
|
||||||
|
|
||||||
|
&:active:not(:disabled)
|
||||||
|
background $theme-color
|
||||||
|
border-color $theme-color
|
||||||
|
|
||||||
|
&:focus
|
||||||
|
&:after
|
||||||
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
position absolute
|
||||||
|
top -5px
|
||||||
|
right -5px
|
||||||
|
bottom -5px
|
||||||
|
left -5px
|
||||||
|
border 2px solid rgba($theme-color, 0.3)
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
|
&:disabled
|
||||||
|
opacity 0.7
|
||||||
|
cursor default
|
||||||
|
|
||||||
|
&.wait
|
||||||
|
background linear-gradient(
|
||||||
|
45deg,
|
||||||
|
darken($theme-color, 10%) 25%,
|
||||||
|
$theme-color 25%,
|
||||||
|
$theme-color 50%,
|
||||||
|
darken($theme-color, 10%) 50%,
|
||||||
|
darken($theme-color, 10%) 75%,
|
||||||
|
$theme-color 75%,
|
||||||
|
$theme-color
|
||||||
|
)
|
||||||
|
background-size 32px 32px
|
||||||
|
animation stripe-bg 1.5s linear infinite
|
||||||
|
opacity 0.7
|
||||||
|
cursor wait
|
||||||
|
|
||||||
|
@keyframes stripe-bg
|
||||||
|
from {background-position: 0 0;}
|
||||||
|
to {background-position: -64px 32px;}
|
||||||
|
|
||||||
|
[ref='upload']
|
||||||
|
[ref='drive']
|
||||||
|
display inline-block
|
||||||
|
cursor pointer
|
||||||
|
padding 0
|
||||||
|
margin 8px 4px 0 0
|
||||||
|
width 40px
|
||||||
|
height 40px
|
||||||
|
font-size 1em
|
||||||
|
color rgba($theme-color, 0.5)
|
||||||
|
background transparent
|
||||||
|
outline none
|
||||||
|
border solid 1px transparent
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background transparent
|
||||||
border-color rgba($theme-color, 0.3)
|
border-color rgba($theme-color, 0.3)
|
||||||
|
|
||||||
> i
|
&:active
|
||||||
color rgba($theme-color, 0.4)
|
color rgba($theme-color, 0.6)
|
||||||
|
background linear-gradient(to bottom, lighten($theme-color, 80%) 0%, lighten($theme-color, 90%) 100%)
|
||||||
|
border-color rgba($theme-color, 0.5)
|
||||||
|
box-shadow 0 2px 4px rgba(0, 0, 0, 0.15) inset
|
||||||
|
|
||||||
> i
|
&:focus
|
||||||
display block
|
&:after
|
||||||
width 60px
|
content ""
|
||||||
height 60px
|
pointer-events none
|
||||||
line-height 60px
|
position absolute
|
||||||
text-align center
|
top -5px
|
||||||
font-size 1.2em
|
right -5px
|
||||||
color rgba($theme-color, 0.2)
|
bottom -5px
|
||||||
|
left -5px
|
||||||
|
border 2px solid rgba($theme-color, 0.3)
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
> mk-uploader
|
> .dropzone
|
||||||
margin 8px 0 0 0
|
|
||||||
padding 8px
|
|
||||||
border solid 1px rgba($theme-color, 0.2)
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
[ref='file']
|
|
||||||
display none
|
|
||||||
|
|
||||||
[ref='text']
|
|
||||||
display block
|
|
||||||
padding 12px
|
|
||||||
margin 0
|
|
||||||
width 100%
|
|
||||||
max-width 100%
|
|
||||||
min-width 100%
|
|
||||||
min-height calc(16px + 12px + 12px)
|
|
||||||
font-size 16px
|
|
||||||
color #333
|
|
||||||
background #fff
|
|
||||||
outline none
|
|
||||||
border solid 1px rgba($theme-color, 0.1)
|
|
||||||
border-radius 4px
|
|
||||||
transition border-color .3s ease
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
border-color rgba($theme-color, 0.2)
|
|
||||||
transition border-color .1s ease
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
color $theme-color
|
|
||||||
border-color rgba($theme-color, 0.5)
|
|
||||||
transition border-color 0s ease
|
|
||||||
|
|
||||||
&:disabled
|
|
||||||
opacity 0.5
|
|
||||||
|
|
||||||
&::-webkit-input-placeholder
|
|
||||||
color rgba($theme-color, 0.3)
|
|
||||||
|
|
||||||
&.withfiles
|
|
||||||
border-bottom solid 1px rgba($theme-color, 0.1) !important
|
|
||||||
border-radius 4px 4px 0 0
|
|
||||||
|
|
||||||
&:hover + .attaches
|
|
||||||
border-color rgba($theme-color, 0.2)
|
|
||||||
transition border-color .1s ease
|
|
||||||
|
|
||||||
&:focus + .attaches
|
|
||||||
border-color rgba($theme-color, 0.5)
|
|
||||||
transition border-color 0s ease
|
|
||||||
|
|
||||||
.text-count
|
|
||||||
pointer-events none
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
bottom 16px
|
|
||||||
right 138px
|
|
||||||
margin 0
|
|
||||||
line-height 40px
|
|
||||||
color rgba($theme-color, 0.5)
|
|
||||||
|
|
||||||
&.over
|
|
||||||
color #ec3828
|
|
||||||
|
|
||||||
[ref='submit']
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
bottom 16px
|
|
||||||
right 16px
|
|
||||||
cursor pointer
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
width 110px
|
|
||||||
height 40px
|
|
||||||
font-size 1em
|
|
||||||
color $theme-color-foreground
|
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
|
||||||
outline none
|
|
||||||
border solid 1px lighten($theme-color, 15%)
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:not(:disabled)
|
|
||||||
font-weight bold
|
|
||||||
|
|
||||||
&:hover:not(:disabled)
|
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
|
||||||
border-color $theme-color
|
|
||||||
|
|
||||||
&:active:not(:disabled)
|
|
||||||
background $theme-color
|
|
||||||
border-color $theme-color
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
position absolute
|
||||||
top -5px
|
left 0
|
||||||
right -5px
|
top 0
|
||||||
bottom -5px
|
width 100%
|
||||||
left -5px
|
height 100%
|
||||||
border 2px solid rgba($theme-color, 0.3)
|
border dashed 2px rgba($theme-color, 0.5)
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
&:disabled
|
|
||||||
opacity 0.7
|
|
||||||
cursor default
|
|
||||||
|
|
||||||
&.wait
|
|
||||||
background linear-gradient(
|
|
||||||
45deg,
|
|
||||||
darken($theme-color, 10%) 25%,
|
|
||||||
$theme-color 25%,
|
|
||||||
$theme-color 50%,
|
|
||||||
darken($theme-color, 10%) 50%,
|
|
||||||
darken($theme-color, 10%) 75%,
|
|
||||||
$theme-color 75%,
|
|
||||||
$theme-color
|
|
||||||
)
|
|
||||||
background-size 32px 32px
|
|
||||||
animation stripe-bg 1.5s linear infinite
|
|
||||||
opacity 0.7
|
|
||||||
cursor wait
|
|
||||||
|
|
||||||
@keyframes stripe-bg
|
|
||||||
from {background-position: 0 0;}
|
|
||||||
to {background-position: -64px 32px;}
|
|
||||||
|
|
||||||
[ref='upload']
|
|
||||||
[ref='drive']
|
|
||||||
display inline-block
|
|
||||||
cursor pointer
|
|
||||||
padding 0
|
|
||||||
margin 8px 4px 0 0
|
|
||||||
width 40px
|
|
||||||
height 40px
|
|
||||||
font-size 1em
|
|
||||||
color rgba($theme-color, 0.5)
|
|
||||||
background transparent
|
|
||||||
outline none
|
|
||||||
border solid 1px transparent
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background transparent
|
|
||||||
border-color rgba($theme-color, 0.3)
|
|
||||||
|
|
||||||
&:active
|
|
||||||
color rgba($theme-color, 0.6)
|
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 80%) 0%, lighten($theme-color, 90%) 100%)
|
|
||||||
border-color rgba($theme-color, 0.5)
|
|
||||||
box-shadow 0 2px 4px rgba(0, 0, 0, 0.15) inset
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
pointer-events none
|
||||||
position absolute
|
|
||||||
top -5px
|
|
||||||
right -5px
|
|
||||||
bottom -5px
|
|
||||||
left -5px
|
|
||||||
border 2px solid rgba($theme-color, 0.3)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
> .dropzone
|
</style>
|
||||||
position absolute
|
<script>
|
||||||
left 0
|
@mixin \api
|
||||||
top 0
|
@mixin \notify
|
||||||
width 100%
|
@mixin \autocomplete
|
||||||
height 100%
|
@mixin \sortable
|
||||||
border dashed 2px rgba($theme-color, 0.5)
|
|
||||||
pointer-events none
|
|
||||||
|
|
||||||
script.
|
@wait = false
|
||||||
@mixin \api
|
@uploadings = []
|
||||||
@mixin \notify
|
|
||||||
@mixin \autocomplete
|
|
||||||
@mixin \sortable
|
|
||||||
|
|
||||||
@wait = false
|
|
||||||
@uploadings = []
|
|
||||||
@files = []
|
|
||||||
@autocomplete = null
|
|
||||||
|
|
||||||
@in-reply-to-post = @opts.reply
|
|
||||||
|
|
||||||
# https://github.com/riot/riot/issues/2080
|
|
||||||
if @in-reply-to-post == '' then @in-reply-to-post = null
|
|
||||||
|
|
||||||
@on \mount ~>
|
|
||||||
@refs.uploader.on \uploaded (file) ~>
|
|
||||||
@add-file file
|
|
||||||
|
|
||||||
@refs.uploader.on \change-uploads (uploads) ~>
|
|
||||||
@trigger \change-uploading-files uploads
|
|
||||||
|
|
||||||
@autocomplete = new @Autocomplete @refs.text
|
|
||||||
@autocomplete.attach!
|
|
||||||
|
|
||||||
@on \unmount ~>
|
|
||||||
@autocomplete.detach!
|
|
||||||
|
|
||||||
@focus = ~>
|
|
||||||
@refs.text.focus!
|
|
||||||
|
|
||||||
@clear = ~>
|
|
||||||
@refs.text.value = ''
|
|
||||||
@files = []
|
@files = []
|
||||||
@trigger \change-files
|
@autocomplete = null
|
||||||
@update!
|
|
||||||
|
|
||||||
@ondragover = (e) ~>
|
@in-reply-to-post = @opts.reply
|
||||||
e.stop-propagation!
|
|
||||||
@draghover = true
|
|
||||||
# ドラッグされてきたものがファイルだったら
|
|
||||||
if e.data-transfer.effect-allowed == \all
|
|
||||||
e.data-transfer.drop-effect = \copy
|
|
||||||
else
|
|
||||||
e.data-transfer.drop-effect = \move
|
|
||||||
return false
|
|
||||||
|
|
||||||
@ondragenter = (e) ~>
|
# https://github.com/riot/riot/issues/2080
|
||||||
@draghover = true
|
if @in-reply-to-post == '' then @in-reply-to-post = null
|
||||||
|
|
||||||
@ondragleave = (e) ~>
|
@on \mount ~>
|
||||||
@draghover = false
|
@refs.uploader.on \uploaded (file) ~>
|
||||||
|
@add-file file
|
||||||
|
|
||||||
@ondrop = (e) ~>
|
@refs.uploader.on \change-uploads (uploads) ~>
|
||||||
e.prevent-default!
|
@trigger \change-uploading-files uploads
|
||||||
e.stop-propagation!
|
|
||||||
@draghover = false
|
|
||||||
|
|
||||||
# ファイルだったら
|
@autocomplete = new @Autocomplete @refs.text
|
||||||
if e.data-transfer.files.length > 0
|
@autocomplete.attach!
|
||||||
Array.prototype.for-each.call e.data-transfer.files, (file) ~>
|
|
||||||
|
@on \unmount ~>
|
||||||
|
@autocomplete.detach!
|
||||||
|
|
||||||
|
@focus = ~>
|
||||||
|
@refs.text.focus!
|
||||||
|
|
||||||
|
@clear = ~>
|
||||||
|
@refs.text.value = ''
|
||||||
|
@files = []
|
||||||
|
@trigger \change-files
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@ondragover = (e) ~>
|
||||||
|
e.stop-propagation!
|
||||||
|
@draghover = true
|
||||||
|
# ドラッグされてきたものがファイルだったら
|
||||||
|
if e.data-transfer.effect-allowed == \all
|
||||||
|
e.data-transfer.drop-effect = \copy
|
||||||
|
else
|
||||||
|
e.data-transfer.drop-effect = \move
|
||||||
|
return false
|
||||||
|
|
||||||
|
@ondragenter = (e) ~>
|
||||||
|
@draghover = true
|
||||||
|
|
||||||
|
@ondragleave = (e) ~>
|
||||||
|
@draghover = false
|
||||||
|
|
||||||
|
@ondrop = (e) ~>
|
||||||
|
e.prevent-default!
|
||||||
|
e.stop-propagation!
|
||||||
|
@draghover = false
|
||||||
|
|
||||||
|
# ファイルだったら
|
||||||
|
if e.data-transfer.files.length > 0
|
||||||
|
Array.prototype.for-each.call e.data-transfer.files, (file) ~>
|
||||||
|
@upload file
|
||||||
|
return false
|
||||||
|
|
||||||
|
# データ取得
|
||||||
|
data = e.data-transfer.get-data 'text'
|
||||||
|
if !data?
|
||||||
|
return false
|
||||||
|
|
||||||
|
try
|
||||||
|
# パース
|
||||||
|
obj = JSON.parse data
|
||||||
|
|
||||||
|
# (ドライブの)ファイルだったら
|
||||||
|
if obj.type == \file
|
||||||
|
@add-file obj.file
|
||||||
|
catch
|
||||||
|
# ignore
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
|
@onkeydown = (e) ~>
|
||||||
|
if (e.which == 10 || e.which == 13) && (e.ctrl-key || e.meta-key)
|
||||||
|
@post!
|
||||||
|
|
||||||
|
@onpaste = (e) ~>
|
||||||
|
data = e.clipboard-data
|
||||||
|
items = data.items
|
||||||
|
for i from 0 to items.length - 1
|
||||||
|
item = items[i]
|
||||||
|
switch (item.kind)
|
||||||
|
| \file =>
|
||||||
|
@upload item.get-as-file!
|
||||||
|
|
||||||
|
@select-file = ~>
|
||||||
|
@refs.file.click!
|
||||||
|
|
||||||
|
@select-file-from-drive = ~>
|
||||||
|
browser = document.body.append-child document.create-element \mk-select-file-from-drive-window
|
||||||
|
i = riot.mount browser, do
|
||||||
|
multiple: true
|
||||||
|
i[0].one \selected (files) ~>
|
||||||
|
files.for-each @add-file
|
||||||
|
|
||||||
|
@change-file = ~>
|
||||||
|
files = @refs.file.files
|
||||||
|
for i from 0 to files.length - 1
|
||||||
|
file = files.item i
|
||||||
@upload file
|
@upload file
|
||||||
return false
|
|
||||||
|
|
||||||
# データ取得
|
@upload = (file) ~>
|
||||||
data = e.data-transfer.get-data 'text'
|
@refs.uploader.upload file
|
||||||
if !data?
|
|
||||||
return false
|
|
||||||
|
|
||||||
try
|
@add-file = (file) ~>
|
||||||
# パース
|
file._remove = ~>
|
||||||
obj = JSON.parse data
|
@files = @files.filter (x) -> x.id != file.id
|
||||||
|
@trigger \change-files @files
|
||||||
|
@update!
|
||||||
|
|
||||||
# (ドライブの)ファイルだったら
|
@files.push file
|
||||||
if obj.type == \file
|
|
||||||
@add-file obj.file
|
|
||||||
catch
|
|
||||||
# ignore
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
@onkeydown = (e) ~>
|
|
||||||
if (e.which == 10 || e.which == 13) && (e.ctrl-key || e.meta-key)
|
|
||||||
@post!
|
|
||||||
|
|
||||||
@onpaste = (e) ~>
|
|
||||||
data = e.clipboard-data
|
|
||||||
items = data.items
|
|
||||||
for i from 0 to items.length - 1
|
|
||||||
item = items[i]
|
|
||||||
switch (item.kind)
|
|
||||||
| \file =>
|
|
||||||
@upload item.get-as-file!
|
|
||||||
|
|
||||||
@select-file = ~>
|
|
||||||
@refs.file.click!
|
|
||||||
|
|
||||||
@select-file-from-drive = ~>
|
|
||||||
browser = document.body.append-child document.create-element \mk-select-file-from-drive-window
|
|
||||||
i = riot.mount browser, do
|
|
||||||
multiple: true
|
|
||||||
i[0].one \selected (files) ~>
|
|
||||||
files.for-each @add-file
|
|
||||||
|
|
||||||
@change-file = ~>
|
|
||||||
files = @refs.file.files
|
|
||||||
for i from 0 to files.length - 1
|
|
||||||
file = files.item i
|
|
||||||
@upload file
|
|
||||||
|
|
||||||
@upload = (file) ~>
|
|
||||||
@refs.uploader.upload file
|
|
||||||
|
|
||||||
@add-file = (file) ~>
|
|
||||||
file._remove = ~>
|
|
||||||
@files = @files.filter (x) -> x.id != file.id
|
|
||||||
@trigger \change-files @files
|
@trigger \change-files @files
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
@files.push file
|
new @Sortable @refs.attaches, do
|
||||||
@trigger \change-files @files
|
draggable: \.file
|
||||||
@update!
|
animation: 150ms
|
||||||
|
|
||||||
new @Sortable @refs.attaches, do
|
@post = (e) ~>
|
||||||
draggable: \.file
|
@wait = true
|
||||||
animation: 150ms
|
|
||||||
|
|
||||||
@post = (e) ~>
|
files = if @files? and @files.length > 0
|
||||||
@wait = true
|
then @files.map (f) -> f.id
|
||||||
|
else undefined
|
||||||
|
|
||||||
files = if @files? and @files.length > 0
|
@api \posts/create do
|
||||||
then @files.map (f) -> f.id
|
text: @refs.text.value
|
||||||
else undefined
|
media_ids: files
|
||||||
|
reply_to_id: if @in-reply-to-post? then @in-reply-to-post.id else undefined
|
||||||
@api \posts/create do
|
.then (data) ~>
|
||||||
text: @refs.text.value
|
@trigger \post
|
||||||
media_ids: files
|
@notify if @in-reply-to-post? then '返信しました!' else '投稿しました!'
|
||||||
reply_to_id: if @in-reply-to-post? then @in-reply-to-post.id else undefined
|
.catch (err) ~>
|
||||||
.then (data) ~>
|
console.error err
|
||||||
@trigger \post
|
@notify '投稿できませんでした'
|
||||||
@notify if @in-reply-to-post? then '返信しました!' else '投稿しました!'
|
.then ~>
|
||||||
.catch (err) ~>
|
@wait = false
|
||||||
console.error err
|
@update!
|
||||||
@notify '投稿できませんでした'
|
</script>
|
||||||
.then ~>
|
</mk-post-form>
|
||||||
@wait = false
|
|
||||||
@update!
|
|
||||||
|
|
|
@ -1,94 +1,93 @@
|
||||||
mk-post-preview(title={ title })
|
<mk-post-preview title="{ title }">
|
||||||
article
|
<article><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar" data-user-preview="{ post.user_id }"/></a>
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username })
|
<div class="main">
|
||||||
img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ post.user_id })
|
<header><a class="name" href="{ CONFIG.url + '/' + post.user.username }" data-user-preview="{ post.user_id }">{ post.user.name }</a><span class="username">@{ post.user.username }</span><a class="time" href="{ CONFIG.url + '/' + post.user.username + '/' + post.id }">
|
||||||
div.main
|
<mk-time time="{ post.created_at }"></mk-time></a></header>
|
||||||
header
|
<div class="body">
|
||||||
a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id })
|
<mk-sub-post-content class="text" post="{ post }"></mk-sub-post-content>
|
||||||
| { post.user.name }
|
</div>
|
||||||
span.username
|
</div>
|
||||||
| @{ post.user.username }
|
</article>
|
||||||
a.time(href={ CONFIG.url + '/' + post.user.username + '/' + post.id })
|
<style type="stylus">
|
||||||
mk-time(time={ post.created_at })
|
:scope
|
||||||
div.body
|
|
||||||
mk-sub-post-content.text(post={ post })
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
font-size 0.9em
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
> article
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
display block
|
||||||
clear both
|
margin 0
|
||||||
|
padding 0
|
||||||
|
font-size 0.9em
|
||||||
|
background #fff
|
||||||
|
|
||||||
&:hover
|
> article
|
||||||
> .main > footer > button
|
|
||||||
color #888
|
|
||||||
|
|
||||||
> .avatar-anchor
|
&:after
|
||||||
display block
|
content ""
|
||||||
float left
|
display block
|
||||||
margin 0 16px 0 0
|
clear both
|
||||||
|
|
||||||
> .avatar
|
&:hover
|
||||||
display block
|
> .main > footer > button
|
||||||
width 52px
|
color #888
|
||||||
height 52px
|
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .main
|
> .avatar-anchor
|
||||||
float left
|
display block
|
||||||
width calc(100% - 68px)
|
float left
|
||||||
|
margin 0 16px 0 0
|
||||||
|
|
||||||
> header
|
> .avatar
|
||||||
margin-bottom 4px
|
display block
|
||||||
white-space nowrap
|
width 52px
|
||||||
|
height 52px
|
||||||
|
margin 0
|
||||||
|
border-radius 8px
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
> .name
|
> .main
|
||||||
display inline
|
float left
|
||||||
margin 0
|
width calc(100% - 68px)
|
||||||
padding 0
|
|
||||||
color #607073
|
|
||||||
font-size 1em
|
|
||||||
font-weight 700
|
|
||||||
text-align left
|
|
||||||
text-decoration none
|
|
||||||
|
|
||||||
&:hover
|
> header
|
||||||
text-decoration underline
|
margin-bottom 4px
|
||||||
|
white-space nowrap
|
||||||
|
|
||||||
> .username
|
> .name
|
||||||
text-align left
|
display inline
|
||||||
margin 0 0 0 8px
|
margin 0
|
||||||
color #d1d8da
|
padding 0
|
||||||
|
color #607073
|
||||||
|
font-size 1em
|
||||||
|
font-weight 700
|
||||||
|
text-align left
|
||||||
|
text-decoration none
|
||||||
|
|
||||||
> .time
|
&:hover
|
||||||
position absolute
|
text-decoration underline
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
color #b2b8bb
|
|
||||||
|
|
||||||
> .body
|
> .username
|
||||||
|
text-align left
|
||||||
|
margin 0 0 0 8px
|
||||||
|
color #d1d8da
|
||||||
|
|
||||||
> .text
|
> .time
|
||||||
cursor default
|
position absolute
|
||||||
margin 0
|
top 0
|
||||||
padding 0
|
right 0
|
||||||
font-size 1.1em
|
color #b2b8bb
|
||||||
color #717171
|
|
||||||
|
|
||||||
script.
|
> .body
|
||||||
@mixin \date-stringify
|
|
||||||
@mixin \user-preview
|
|
||||||
|
|
||||||
@post = @opts.post
|
> .text
|
||||||
|
cursor default
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
font-size 1.1em
|
||||||
|
color #717171
|
||||||
|
|
||||||
@title = @date-stringify @post.created_at
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \date-stringify
|
||||||
|
@mixin \user-preview
|
||||||
|
|
||||||
|
@post = @opts.post
|
||||||
|
|
||||||
|
@title = @date-stringify @post.created_at
|
||||||
|
</script>
|
||||||
|
</mk-post-preview>
|
||||||
|
|
|
@ -1,72 +1,75 @@
|
||||||
mk-post-status-graph
|
<mk-post-status-graph>
|
||||||
canvas@canv(width={ opts.width }, height={ opts.height })
|
<canvas ref="canv" width="{ opts.width }" height="{ opts.height }"></canvas>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
> canvas
|
||||||
display block
|
margin 0 auto
|
||||||
|
|
||||||
> canvas
|
</style>
|
||||||
margin 0 auto
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \is-promise
|
||||||
|
|
||||||
script.
|
@post = null
|
||||||
@mixin \api
|
@post-promise = if @is-promise @opts.post then @opts.post else Promise.resolve @opts.post
|
||||||
@mixin \is-promise
|
|
||||||
|
|
||||||
@post = null
|
@on \mount ~>
|
||||||
@post-promise = if @is-promise @opts.post then @opts.post else Promise.resolve @opts.post
|
post <~ @post-promise.then
|
||||||
|
@post = post
|
||||||
|
@update!
|
||||||
|
|
||||||
@on \mount ~>
|
@api \aggregation/posts/like do
|
||||||
post <~ @post-promise.then
|
|
||||||
@post = post
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@api \aggregation/posts/like do
|
|
||||||
post_id: @post.id
|
|
||||||
limit: 30days
|
|
||||||
.then (likes) ~>
|
|
||||||
likes = likes.reverse!
|
|
||||||
|
|
||||||
@api \aggregation/posts/repost do
|
|
||||||
post_id: @post.id
|
post_id: @post.id
|
||||||
limit: 30days
|
limit: 30days
|
||||||
.then (repost) ~>
|
.then (likes) ~>
|
||||||
repost = repost.reverse!
|
likes = likes.reverse!
|
||||||
|
|
||||||
@api \aggregation/posts/reply do
|
@api \aggregation/posts/repost do
|
||||||
post_id: @post.id
|
post_id: @post.id
|
||||||
limit: 30days
|
limit: 30days
|
||||||
.then (replies) ~>
|
.then (repost) ~>
|
||||||
replies = replies.reverse!
|
repost = repost.reverse!
|
||||||
|
|
||||||
new Chart @refs.canv, do
|
@api \aggregation/posts/reply do
|
||||||
type: \bar
|
post_id: @post.id
|
||||||
data:
|
limit: 30days
|
||||||
labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
|
.then (replies) ~>
|
||||||
datasets: [
|
replies = replies.reverse!
|
||||||
{
|
|
||||||
label: \いいね
|
new Chart @refs.canv, do
|
||||||
type: \line
|
type: \bar
|
||||||
data: likes.map (x) ~> x.count
|
data:
|
||||||
line-tension: 0
|
labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + '日' else ''
|
||||||
border-width: 2
|
datasets: [
|
||||||
fill: true
|
{
|
||||||
background-color: 'rgba(247, 121, 108, 0.2)'
|
label: \いいね
|
||||||
point-background-color: \#fff
|
type: \line
|
||||||
point-radius: 4
|
data: likes.map (x) ~> x.count
|
||||||
point-border-width: 2
|
line-tension: 0
|
||||||
border-color: \#F7796C
|
border-width: 2
|
||||||
},
|
fill: true
|
||||||
{
|
background-color: 'rgba(247, 121, 108, 0.2)'
|
||||||
label: \返信
|
point-background-color: \#fff
|
||||||
type: \bar
|
point-radius: 4
|
||||||
data: replies.map (x) ~> x.count
|
point-border-width: 2
|
||||||
background-color: \#555
|
border-color: \#F7796C
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: \Repost
|
label: \返信
|
||||||
type: \bar
|
type: \bar
|
||||||
data: repost.map (x) ~> x.count
|
data: replies.map (x) ~> x.count
|
||||||
background-color: \#a2d61e
|
background-color: \#555
|
||||||
}
|
},
|
||||||
]
|
{
|
||||||
options:
|
label: \Repost
|
||||||
responsive: false
|
type: \bar
|
||||||
|
data: repost.map (x) ~> x.count
|
||||||
|
background-color: \#a2d61e
|
||||||
|
}
|
||||||
|
]
|
||||||
|
options:
|
||||||
|
responsive: false
|
||||||
|
</script>
|
||||||
|
</mk-post-status-graph>
|
||||||
|
|
|
@ -1,92 +1,94 @@
|
||||||
mk-progress-dialog
|
<mk-progress-dialog>
|
||||||
mk-window@window(is-modal={ false }, can-close={ false }, width={ '500px' })
|
<mk-window ref="window" is-modal="{ false }" can-close="{ false }" width="{ '500px' }">
|
||||||
<yield to="header">
|
<yield to="header">{ parent.title }
|
||||||
| { parent.title }
|
<mk-ellipsis></mk-ellipsis></yield>
|
||||||
mk-ellipsis
|
<yield to="content">
|
||||||
</yield>
|
<div class="body">
|
||||||
<yield to="content">
|
<p class="init" if="{ isNaN(parent.value) }">待機中
|
||||||
div.body
|
<mk-ellipsis></mk-ellipsis>
|
||||||
p.init(if={ isNaN(parent.value) })
|
</p>
|
||||||
| 待機中
|
<p class="percentage" if="{ !isNaN(parent.value) }">{ Math.floor((parent.value / parent.max) * 100) }</p>
|
||||||
mk-ellipsis
|
<progress if="{ !isNaN(parent.value) && parent.value < parent.max }" value="{ isNaN(parent.value) ? 0 : parent.value }" max="{ parent.max }"></progress>
|
||||||
p.percentage(if={ !isNaN(parent.value) }) { Math.floor((parent.value / parent.max) * 100) }
|
<div class="progress waiting" if="{ parent.value >= parent.max }"></div>
|
||||||
progress(if={ !isNaN(parent.value) && parent.value < parent.max }, value={ isNaN(parent.value) ? 0 : parent.value }, max={ parent.max })
|
</div></yield>
|
||||||
div.progress.waiting(if={ parent.value >= parent.max })
|
</mk-window>
|
||||||
</yield>
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
> mk-window
|
||||||
display block
|
[data-yield='content']
|
||||||
|
|
||||||
> mk-window
|
> .body
|
||||||
[data-yield='content']
|
padding 18px 24px 24px 24px
|
||||||
|
|
||||||
> .body
|
> .init
|
||||||
padding 18px 24px 24px 24px
|
display block
|
||||||
|
margin 0
|
||||||
|
text-align center
|
||||||
|
color rgba(#000, 0.7)
|
||||||
|
|
||||||
> .init
|
> .percentage
|
||||||
display block
|
display block
|
||||||
margin 0
|
margin 0 0 4px 0
|
||||||
text-align center
|
text-align center
|
||||||
color rgba(#000, 0.7)
|
line-height 16px
|
||||||
|
color rgba($theme-color, 0.7)
|
||||||
|
|
||||||
> .percentage
|
&:after
|
||||||
display block
|
content '%'
|
||||||
margin 0 0 4px 0
|
|
||||||
text-align center
|
|
||||||
line-height 16px
|
|
||||||
color rgba($theme-color, 0.7)
|
|
||||||
|
|
||||||
&:after
|
> progress
|
||||||
content '%'
|
> .progress
|
||||||
|
display block
|
||||||
|
margin 0
|
||||||
|
width 100%
|
||||||
|
height 10px
|
||||||
|
background transparent
|
||||||
|
border none
|
||||||
|
border-radius 4px
|
||||||
|
overflow hidden
|
||||||
|
|
||||||
> progress
|
&::-webkit-progress-value
|
||||||
> .progress
|
background $theme-color
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
width 100%
|
|
||||||
height 10px
|
|
||||||
background transparent
|
|
||||||
border none
|
|
||||||
border-radius 4px
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
&::-webkit-progress-value
|
&::-webkit-progress-bar
|
||||||
background $theme-color
|
background rgba($theme-color, 0.1)
|
||||||
|
|
||||||
&::-webkit-progress-bar
|
> .progress
|
||||||
background rgba($theme-color, 0.1)
|
background linear-gradient(
|
||||||
|
45deg,
|
||||||
|
lighten($theme-color, 30%) 25%,
|
||||||
|
$theme-color 25%,
|
||||||
|
$theme-color 50%,
|
||||||
|
lighten($theme-color, 30%) 50%,
|
||||||
|
lighten($theme-color, 30%) 75%,
|
||||||
|
$theme-color 75%,
|
||||||
|
$theme-color
|
||||||
|
)
|
||||||
|
background-size 32px 32px
|
||||||
|
animation progress-dialog-tag-progress-waiting 1.5s linear infinite
|
||||||
|
|
||||||
> .progress
|
@keyframes progress-dialog-tag-progress-waiting
|
||||||
background linear-gradient(
|
from {background-position: 0 0;}
|
||||||
45deg,
|
to {background-position: -64px 32px;}
|
||||||
lighten($theme-color, 30%) 25%,
|
|
||||||
$theme-color 25%,
|
|
||||||
$theme-color 50%,
|
|
||||||
lighten($theme-color, 30%) 50%,
|
|
||||||
lighten($theme-color, 30%) 75%,
|
|
||||||
$theme-color 75%,
|
|
||||||
$theme-color
|
|
||||||
)
|
|
||||||
background-size 32px 32px
|
|
||||||
animation progress-dialog-tag-progress-waiting 1.5s linear infinite
|
|
||||||
|
|
||||||
@keyframes progress-dialog-tag-progress-waiting
|
</style>
|
||||||
from {background-position: 0 0;}
|
<script>
|
||||||
to {background-position: -64px 32px;}
|
@title = @opts.title
|
||||||
|
@value = parse-int @opts.value, 10
|
||||||
|
@max = parse-int @opts.max, 10
|
||||||
|
|
||||||
script.
|
@on \mount ~>
|
||||||
@title = @opts.title
|
@refs.window.on \closed ~>
|
||||||
@value = parse-int @opts.value, 10
|
@unmount!
|
||||||
@max = parse-int @opts.max, 10
|
|
||||||
|
|
||||||
@on \mount ~>
|
@update-progress = (value, max) ~>
|
||||||
@refs.window.on \closed ~>
|
@value = parse-int value, 10
|
||||||
@unmount!
|
@max = parse-int max, 10
|
||||||
|
@update!
|
||||||
|
|
||||||
@update-progress = (value, max) ~>
|
@close = ~>
|
||||||
@value = parse-int value, 10
|
@refs.window.close!
|
||||||
@max = parse-int max, 10
|
</script>
|
||||||
@update!
|
</mk-progress-dialog>
|
||||||
|
|
||||||
@close = ~>
|
|
||||||
@refs.window.close!
|
|
||||||
|
|
|
@ -1,38 +1,36 @@
|
||||||
mk-repost-form-window
|
<mk-repost-form-window>
|
||||||
mk-window@window(is-modal={ true }, colored={ true })
|
<mk-window ref="window" is-modal="{ true }" colored="{ true }"><yield to="header"><i class="fa fa-retweet"></i>この投稿をRepostしますか?</yield>
|
||||||
<yield to="header">
|
<yield to="content">
|
||||||
i.fa.fa-retweet
|
<mk-repost-form ref="form" post="{ parent.opts.post }"></mk-repost-form></yield>
|
||||||
| この投稿をRepostしますか?
|
</mk-window>
|
||||||
</yield>
|
<style type="stylus">
|
||||||
<yield to="content">
|
:scope
|
||||||
mk-repost-form@form(post={ parent.opts.post })
|
> mk-window
|
||||||
</yield>
|
[data-yield='header']
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
style.
|
</style>
|
||||||
> mk-window
|
<script>
|
||||||
[data-yield='header']
|
@on-document-keydown = (e) ~>
|
||||||
> i
|
tag = e.target.tag-name.to-lower-case!
|
||||||
margin-right 4px
|
if tag != \input and tag != \textarea
|
||||||
|
if e.which == 27 # Esc
|
||||||
|
@refs.window.close!
|
||||||
|
|
||||||
script.
|
@on \mount ~>
|
||||||
|
@refs.window.refs.form.on \cancel ~>
|
||||||
@on-document-keydown = (e) ~>
|
|
||||||
tag = e.target.tag-name.to-lower-case!
|
|
||||||
if tag != \input and tag != \textarea
|
|
||||||
if e.which == 27 # Esc
|
|
||||||
@refs.window.close!
|
@refs.window.close!
|
||||||
|
|
||||||
@on \mount ~>
|
@refs.window.refs.form.on \posted ~>
|
||||||
@refs.window.refs.form.on \cancel ~>
|
@refs.window.close!
|
||||||
@refs.window.close!
|
|
||||||
|
|
||||||
@refs.window.refs.form.on \posted ~>
|
document.add-event-listener \keydown @on-document-keydown
|
||||||
@refs.window.close!
|
|
||||||
|
|
||||||
document.add-event-listener \keydown @on-document-keydown
|
@refs.window.on \closed ~>
|
||||||
|
@unmount!
|
||||||
|
|
||||||
@refs.window.on \closed ~>
|
@on \unmount ~>
|
||||||
@unmount!
|
document.remove-event-listener \keydown @on-document-keydown
|
||||||
|
</script>
|
||||||
@on \unmount ~>
|
</mk-repost-form-window>
|
||||||
document.remove-event-listener \keydown @on-document-keydown
|
|
||||||
|
|
|
@ -1,140 +1,144 @@
|
||||||
mk-repost-form
|
<mk-repost-form>
|
||||||
mk-post-preview(post={ opts.post })
|
<mk-post-preview post="{ opts.post }"></mk-post-preview>
|
||||||
div.form(if={ quote })
|
<div class="form" if="{ quote }">
|
||||||
textarea@text(disabled={ wait }, placeholder='この投稿を引用...')
|
<textarea ref="text" disabled="{ wait }" placeholder="この投稿を引用..."></textarea>
|
||||||
footer
|
</div>
|
||||||
a.quote(if={ !quote }, onclick={ onquote }) 引用する...
|
<footer><a class="quote" if="{ !quote }" onclick="{ onquote }">引用する...</a>
|
||||||
button.cancel(onclick={ cancel }) キャンセル
|
<button class="cancel" onclick="{ cancel }">キャンセル</button>
|
||||||
button.ok(onclick={ ok }) Repost
|
<button class="ok" onclick="{ ok }">Repost</button>
|
||||||
|
</footer>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
|
||||||
style.
|
> mk-post-preview
|
||||||
|
margin 16px 22px
|
||||||
|
|
||||||
> mk-post-preview
|
> .form
|
||||||
margin 16px 22px
|
[ref='text']
|
||||||
|
display block
|
||||||
|
padding 12px
|
||||||
|
margin 0
|
||||||
|
width 100%
|
||||||
|
max-width 100%
|
||||||
|
min-width 100%
|
||||||
|
min-height calc(1em + 12px + 12px)
|
||||||
|
font-size 1em
|
||||||
|
color #333
|
||||||
|
background #fff
|
||||||
|
outline none
|
||||||
|
border solid 1px rgba($theme-color, 0.1)
|
||||||
|
border-radius 4px
|
||||||
|
transition border-color .3s ease
|
||||||
|
|
||||||
> .form
|
&:hover
|
||||||
[ref='text']
|
border-color rgba($theme-color, 0.2)
|
||||||
display block
|
transition border-color .1s ease
|
||||||
padding 12px
|
|
||||||
margin 0
|
|
||||||
width 100%
|
|
||||||
max-width 100%
|
|
||||||
min-width 100%
|
|
||||||
min-height calc(1em + 12px + 12px)
|
|
||||||
font-size 1em
|
|
||||||
color #333
|
|
||||||
background #fff
|
|
||||||
outline none
|
|
||||||
border solid 1px rgba($theme-color, 0.1)
|
|
||||||
border-radius 4px
|
|
||||||
transition border-color .3s ease
|
|
||||||
|
|
||||||
&:hover
|
&:focus
|
||||||
border-color rgba($theme-color, 0.2)
|
color $theme-color
|
||||||
transition border-color .1s ease
|
border-color rgba($theme-color, 0.5)
|
||||||
|
transition border-color 0s ease
|
||||||
|
|
||||||
&:focus
|
&:disabled
|
||||||
color $theme-color
|
opacity 0.5
|
||||||
border-color rgba($theme-color, 0.5)
|
|
||||||
transition border-color 0s ease
|
|
||||||
|
|
||||||
&:disabled
|
&::-webkit-input-placeholder
|
||||||
opacity 0.5
|
color rgba($theme-color, 0.3)
|
||||||
|
|
||||||
&::-webkit-input-placeholder
|
> div
|
||||||
color rgba($theme-color, 0.3)
|
padding 16px
|
||||||
|
|
||||||
> div
|
> footer
|
||||||
padding 16px
|
height 72px
|
||||||
|
background lighten($theme-color, 95%)
|
||||||
|
|
||||||
> footer
|
> .quote
|
||||||
height 72px
|
|
||||||
background lighten($theme-color, 95%)
|
|
||||||
|
|
||||||
> .quote
|
|
||||||
position absolute
|
|
||||||
bottom 16px
|
|
||||||
left 28px
|
|
||||||
line-height 40px
|
|
||||||
|
|
||||||
button
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
bottom 16px
|
|
||||||
cursor pointer
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
width 120px
|
|
||||||
height 40px
|
|
||||||
font-size 1em
|
|
||||||
outline none
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
position absolute
|
||||||
top -5px
|
bottom 16px
|
||||||
right -5px
|
left 28px
|
||||||
bottom -5px
|
line-height 40px
|
||||||
left -5px
|
|
||||||
border 2px solid rgba($theme-color, 0.3)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
> .cancel
|
button
|
||||||
right 148px
|
display block
|
||||||
color #888
|
position absolute
|
||||||
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
bottom 16px
|
||||||
border solid 1px #e2e2e2
|
cursor pointer
|
||||||
|
padding 0
|
||||||
|
margin 0
|
||||||
|
width 120px
|
||||||
|
height 40px
|
||||||
|
font-size 1em
|
||||||
|
outline none
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
&:hover
|
&:focus
|
||||||
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
&:after
|
||||||
border-color #dcdcdc
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
position absolute
|
||||||
|
top -5px
|
||||||
|
right -5px
|
||||||
|
bottom -5px
|
||||||
|
left -5px
|
||||||
|
border 2px solid rgba($theme-color, 0.3)
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
&:active
|
> .cancel
|
||||||
background #ececec
|
right 148px
|
||||||
border-color #dcdcdc
|
color #888
|
||||||
|
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
||||||
|
border solid 1px #e2e2e2
|
||||||
|
|
||||||
> .ok
|
&:hover
|
||||||
right 16px
|
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
||||||
font-weight bold
|
border-color #dcdcdc
|
||||||
color $theme-color-foreground
|
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
|
||||||
border solid 1px lighten($theme-color, 15%)
|
|
||||||
|
|
||||||
&:hover
|
&:active
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
background #ececec
|
||||||
border-color $theme-color
|
border-color #dcdcdc
|
||||||
|
|
||||||
&:active
|
> .ok
|
||||||
background $theme-color
|
right 16px
|
||||||
border-color $theme-color
|
font-weight bold
|
||||||
|
color $theme-color-foreground
|
||||||
|
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
||||||
|
border solid 1px lighten($theme-color, 15%)
|
||||||
|
|
||||||
script.
|
&:hover
|
||||||
@mixin \api
|
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
||||||
@mixin \notify
|
border-color $theme-color
|
||||||
|
|
||||||
@wait = false
|
&:active
|
||||||
@quote = false
|
background $theme-color
|
||||||
|
border-color $theme-color
|
||||||
|
|
||||||
@cancel = ~>
|
</style>
|
||||||
@trigger \cancel
|
<script>
|
||||||
|
@mixin \api
|
||||||
|
@mixin \notify
|
||||||
|
|
||||||
@ok = ~>
|
@wait = false
|
||||||
@wait = true
|
@quote = false
|
||||||
@api \posts/create do
|
|
||||||
repost_id: @opts.post.id
|
|
||||||
text: if @quote then @refs.text.value else undefined
|
|
||||||
.then (data) ~>
|
|
||||||
@trigger \posted
|
|
||||||
@notify 'Repostしました!'
|
|
||||||
.catch (err) ~>
|
|
||||||
console.error err
|
|
||||||
@notify 'Repostできませんでした'
|
|
||||||
.then ~>
|
|
||||||
@wait = false
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@onquote = ~>
|
@cancel = ~>
|
||||||
@quote = true
|
@trigger \cancel
|
||||||
|
|
||||||
|
@ok = ~>
|
||||||
|
@wait = true
|
||||||
|
@api \posts/create do
|
||||||
|
repost_id: @opts.post.id
|
||||||
|
text: if @quote then @refs.text.value else undefined
|
||||||
|
.then (data) ~>
|
||||||
|
@trigger \posted
|
||||||
|
@notify 'Repostしました!'
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
@notify 'Repostできませんでした'
|
||||||
|
.then ~>
|
||||||
|
@wait = false
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@onquote = ~>
|
||||||
|
@quote = true
|
||||||
|
</script>
|
||||||
|
</mk-repost-form>
|
||||||
|
|
|
@ -1,88 +1,86 @@
|
||||||
mk-search-posts
|
<mk-search-posts>
|
||||||
div.loading(if={ is-loading })
|
<div class="loading" if="{ isLoading }">
|
||||||
mk-ellipsis-icon
|
<mk-ellipsis-icon></mk-ellipsis-icon>
|
||||||
p.empty(if={ is-empty })
|
</div>
|
||||||
i.fa.fa-search
|
<p class="empty" if="{ isEmpty }"><i class="fa fa-search"></i>「{ query }」に関する投稿は見つかりませんでした。</p>
|
||||||
| 「{ query }」に関する投稿は見つかりませんでした。
|
<mk-timeline ref="timeline"><yield to="footer"><i class="fa fa-moon-o" if="{ !parent.moreLoading }"></i><i class="fa fa-spinner fa-pulse fa-fw" if="{ parent.moreLoading }"></i></yield></mk-timeline>
|
||||||
mk-timeline@timeline
|
<style type="stylus">
|
||||||
<yield to="footer">
|
:scope
|
||||||
i.fa.fa-moon-o(if={ !parent.more-loading })
|
|
||||||
i.fa.fa-spinner.fa-pulse.fa-fw(if={ parent.more-loading })
|
|
||||||
</yield>
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
> .loading
|
|
||||||
padding 64px 0
|
|
||||||
|
|
||||||
> .empty
|
|
||||||
display block
|
|
||||||
margin 0 auto
|
|
||||||
padding 32px
|
|
||||||
max-width 400px
|
|
||||||
text-align center
|
|
||||||
color #999
|
|
||||||
|
|
||||||
> i
|
|
||||||
display block
|
display block
|
||||||
margin-bottom 16px
|
background #fff
|
||||||
font-size 3em
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
script.
|
> .loading
|
||||||
@mixin \api
|
padding 64px 0
|
||||||
@mixin \get-post-summary
|
|
||||||
|
|
||||||
@query = @opts.query
|
> .empty
|
||||||
@is-loading = true
|
display block
|
||||||
@is-empty = false
|
margin 0 auto
|
||||||
@more-loading = false
|
padding 32px
|
||||||
@page = 0
|
max-width 400px
|
||||||
|
text-align center
|
||||||
|
color #999
|
||||||
|
|
||||||
@on \mount ~>
|
> i
|
||||||
document.add-event-listener \keydown @on-document-keydown
|
display block
|
||||||
window.add-event-listener \scroll @on-scroll
|
margin-bottom 16px
|
||||||
|
font-size 3em
|
||||||
|
color #ccc
|
||||||
|
|
||||||
@api \posts/search do
|
</style>
|
||||||
query: @query
|
<script>
|
||||||
.then (posts) ~>
|
@mixin \api
|
||||||
@is-loading = false
|
@mixin \get-post-summary
|
||||||
@is-empty = posts.length == 0
|
|
||||||
|
@query = @opts.query
|
||||||
|
@is-loading = true
|
||||||
|
@is-empty = false
|
||||||
|
@more-loading = false
|
||||||
|
@page = 0
|
||||||
|
|
||||||
|
@on \mount ~>
|
||||||
|
document.add-event-listener \keydown @on-document-keydown
|
||||||
|
window.add-event-listener \scroll @on-scroll
|
||||||
|
|
||||||
|
@api \posts/search do
|
||||||
|
query: @query
|
||||||
|
.then (posts) ~>
|
||||||
|
@is-loading = false
|
||||||
|
@is-empty = posts.length == 0
|
||||||
|
@update!
|
||||||
|
@refs.timeline.set-posts posts
|
||||||
|
@trigger \loaded
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
|
@on \unmount ~>
|
||||||
|
document.remove-event-listener \keydown @on-document-keydown
|
||||||
|
window.remove-event-listener \scroll @on-scroll
|
||||||
|
|
||||||
|
@on-document-keydown = (e) ~>
|
||||||
|
tag = e.target.tag-name.to-lower-case!
|
||||||
|
if tag != \input and tag != \textarea
|
||||||
|
if e.which == 84 # t
|
||||||
|
@refs.timeline.focus!
|
||||||
|
|
||||||
|
@more = ~>
|
||||||
|
if @more-loading or @is-loading or @timeline.posts.length == 0
|
||||||
|
return
|
||||||
|
@more-loading = true
|
||||||
@update!
|
@update!
|
||||||
@refs.timeline.set-posts posts
|
@api \posts/search do
|
||||||
@trigger \loaded
|
query: @query
|
||||||
.catch (err) ~>
|
page: @page + 1
|
||||||
console.error err
|
.then (posts) ~>
|
||||||
|
@more-loading = false
|
||||||
|
@page++
|
||||||
|
@update!
|
||||||
|
@refs.timeline.prepend-posts posts
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
@on \unmount ~>
|
@on-scroll = ~>
|
||||||
document.remove-event-listener \keydown @on-document-keydown
|
current = window.scroll-y + window.inner-height
|
||||||
window.remove-event-listener \scroll @on-scroll
|
if current > document.body.offset-height - 16 # 遊び
|
||||||
|
@more!
|
||||||
@on-document-keydown = (e) ~>
|
</script>
|
||||||
tag = e.target.tag-name.to-lower-case!
|
</mk-search-posts>
|
||||||
if tag != \input and tag != \textarea
|
|
||||||
if e.which == 84 # t
|
|
||||||
@refs.timeline.focus!
|
|
||||||
|
|
||||||
@more = ~>
|
|
||||||
if @more-loading or @is-loading or @timeline.posts.length == 0
|
|
||||||
return
|
|
||||||
@more-loading = true
|
|
||||||
@update!
|
|
||||||
@api \posts/search do
|
|
||||||
query: @query
|
|
||||||
page: @page + 1
|
|
||||||
.then (posts) ~>
|
|
||||||
@more-loading = false
|
|
||||||
@page++
|
|
||||||
@update!
|
|
||||||
@refs.timeline.prepend-posts posts
|
|
||||||
.catch (err) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@on-scroll = ~>
|
|
||||||
current = window.scroll-y + window.inner-height
|
|
||||||
if current > document.body.offset-height - 16 # 遊び
|
|
||||||
@more!
|
|
||||||
|
|
|
@ -1,28 +1,32 @@
|
||||||
mk-search
|
<mk-search>
|
||||||
header
|
<header>
|
||||||
h1 { query }
|
<h1>{ query }</h1>
|
||||||
mk-search-posts@posts(query={ query })
|
</header>
|
||||||
|
<mk-search-posts ref="posts" query="{ query }"></mk-search-posts>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
padding-bottom 32px
|
||||||
|
|
||||||
style.
|
> header
|
||||||
display block
|
width 100%
|
||||||
padding-bottom 32px
|
max-width 600px
|
||||||
|
margin 0 auto
|
||||||
|
color #555
|
||||||
|
|
||||||
> header
|
> mk-search-posts
|
||||||
width 100%
|
max-width 600px
|
||||||
max-width 600px
|
margin 0 auto
|
||||||
margin 0 auto
|
border solid 1px rgba(0, 0, 0, 0.075)
|
||||||
color #555
|
border-radius 6px
|
||||||
|
overflow hidden
|
||||||
|
|
||||||
> mk-search-posts
|
</style>
|
||||||
max-width 600px
|
<script>
|
||||||
margin 0 auto
|
@query = @opts.query
|
||||||
border solid 1px rgba(0, 0, 0, 0.075)
|
|
||||||
border-radius 6px
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
script.
|
@on \mount ~>
|
||||||
@query = @opts.query
|
@refs.posts.on \loaded ~>
|
||||||
|
@trigger \loaded
|
||||||
@on \mount ~>
|
</script>
|
||||||
@refs.posts.on \loaded ~>
|
</mk-search>
|
||||||
@trigger \loaded
|
|
||||||
|
|
|
@ -1,160 +1,161 @@
|
||||||
mk-select-file-from-drive-window
|
<mk-select-file-from-drive-window>
|
||||||
mk-window@window(is-modal={ true }, width={ '800px' }, height={ '500px' })
|
<mk-window ref="window" is-modal="{ true }" width="{ '800px' }" height="{ '500px' }"><yield to="header">
|
||||||
<yield to="header">
|
<mk-raw content="{ parent.title }"></mk-raw><span class="count" if="{ parent.multiple && parent.file.length > 0 }">({ parent.file.length }ファイル選択中)</span></yield>
|
||||||
mk-raw(content={ parent.title })
|
<yield to="content">
|
||||||
span.count(if={ parent.multiple && parent.file.length > 0 }) ({ parent.file.length }ファイル選択中)
|
<mk-drive-browser ref="browser" multiple="{ parent.multiple }"></mk-drive-browser>
|
||||||
</yield>
|
<div>
|
||||||
<yield to="content">
|
<button class="upload" title="PCからドライブにファイルをアップロード" onclick="{ parent.upload }"><i class="fa fa-upload"></i></button>
|
||||||
mk-drive-browser@browser(multiple={ parent.multiple })
|
<button class="cancel" onclick="{ parent.close }">キャンセル</button>
|
||||||
div
|
<button class="ok" disabled="{ parent.multiple && parent.file.length == 0 }" onclick="{ parent.ok }">決定</button>
|
||||||
button.upload(title='PCからドライブにファイルをアップロード', onclick={ parent.upload }): i.fa.fa-upload
|
</div></yield>
|
||||||
button.cancel(onclick={ parent.close }) キャンセル
|
</mk-window>
|
||||||
button.ok(disabled={ parent.multiple && parent.file.length == 0 }, onclick={ parent.ok }) 決定
|
<style type="stylus">
|
||||||
</yield>
|
:scope
|
||||||
|
> mk-window
|
||||||
|
[data-yield='header']
|
||||||
|
> mk-raw
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
style.
|
.count
|
||||||
> mk-window
|
margin-left 8px
|
||||||
[data-yield='header']
|
|
||||||
> mk-raw
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
.count
|
|
||||||
margin-left 8px
|
|
||||||
opacity 0.7
|
|
||||||
|
|
||||||
[data-yield='content']
|
|
||||||
> mk-drive-browser
|
|
||||||
height calc(100% - 72px)
|
|
||||||
|
|
||||||
> div
|
|
||||||
height 72px
|
|
||||||
background lighten($theme-color, 95%)
|
|
||||||
|
|
||||||
.upload
|
|
||||||
display inline-block
|
|
||||||
position absolute
|
|
||||||
top 8px
|
|
||||||
left 16px
|
|
||||||
cursor pointer
|
|
||||||
padding 0
|
|
||||||
margin 8px 4px 0 0
|
|
||||||
width 40px
|
|
||||||
height 40px
|
|
||||||
font-size 1em
|
|
||||||
color rgba($theme-color, 0.5)
|
|
||||||
background transparent
|
|
||||||
outline none
|
|
||||||
border solid 1px transparent
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background transparent
|
|
||||||
border-color rgba($theme-color, 0.3)
|
|
||||||
|
|
||||||
&:active
|
|
||||||
color rgba($theme-color, 0.6)
|
|
||||||
background transparent
|
|
||||||
border-color rgba($theme-color, 0.5)
|
|
||||||
box-shadow 0 2px 4px rgba(darken($theme-color, 50%), 0.15) inset
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
|
||||||
top -5px
|
|
||||||
right -5px
|
|
||||||
bottom -5px
|
|
||||||
left -5px
|
|
||||||
border 2px solid rgba($theme-color, 0.3)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
.ok
|
|
||||||
.cancel
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
bottom 16px
|
|
||||||
cursor pointer
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
width 120px
|
|
||||||
height 40px
|
|
||||||
font-size 1em
|
|
||||||
outline none
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
|
||||||
top -5px
|
|
||||||
right -5px
|
|
||||||
bottom -5px
|
|
||||||
left -5px
|
|
||||||
border 2px solid rgba($theme-color, 0.3)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
&:disabled
|
|
||||||
opacity 0.7
|
opacity 0.7
|
||||||
cursor default
|
|
||||||
|
|
||||||
.ok
|
[data-yield='content']
|
||||||
right 16px
|
> mk-drive-browser
|
||||||
color $theme-color-foreground
|
height calc(100% - 72px)
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
|
||||||
border solid 1px lighten($theme-color, 15%)
|
|
||||||
|
|
||||||
&:not(:disabled)
|
> div
|
||||||
font-weight bold
|
height 72px
|
||||||
|
background lighten($theme-color, 95%)
|
||||||
|
|
||||||
&:hover:not(:disabled)
|
.upload
|
||||||
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
display inline-block
|
||||||
border-color $theme-color
|
position absolute
|
||||||
|
top 8px
|
||||||
|
left 16px
|
||||||
|
cursor pointer
|
||||||
|
padding 0
|
||||||
|
margin 8px 4px 0 0
|
||||||
|
width 40px
|
||||||
|
height 40px
|
||||||
|
font-size 1em
|
||||||
|
color rgba($theme-color, 0.5)
|
||||||
|
background transparent
|
||||||
|
outline none
|
||||||
|
border solid 1px transparent
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
&:active:not(:disabled)
|
&:hover
|
||||||
background $theme-color
|
background transparent
|
||||||
border-color $theme-color
|
border-color rgba($theme-color, 0.3)
|
||||||
|
|
||||||
.cancel
|
&:active
|
||||||
right 148px
|
color rgba($theme-color, 0.6)
|
||||||
color #888
|
background transparent
|
||||||
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
border-color rgba($theme-color, 0.5)
|
||||||
border solid 1px #e2e2e2
|
box-shadow 0 2px 4px rgba(darken($theme-color, 50%), 0.15) inset
|
||||||
|
|
||||||
&:hover
|
&:focus
|
||||||
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
&:after
|
||||||
border-color #dcdcdc
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
position absolute
|
||||||
|
top -5px
|
||||||
|
right -5px
|
||||||
|
bottom -5px
|
||||||
|
left -5px
|
||||||
|
border 2px solid rgba($theme-color, 0.3)
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
&:active
|
.ok
|
||||||
background #ececec
|
.cancel
|
||||||
border-color #dcdcdc
|
display block
|
||||||
|
position absolute
|
||||||
|
bottom 16px
|
||||||
|
cursor pointer
|
||||||
|
padding 0
|
||||||
|
margin 0
|
||||||
|
width 120px
|
||||||
|
height 40px
|
||||||
|
font-size 1em
|
||||||
|
outline none
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
script.
|
&:focus
|
||||||
@file = []
|
&:after
|
||||||
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
position absolute
|
||||||
|
top -5px
|
||||||
|
right -5px
|
||||||
|
bottom -5px
|
||||||
|
left -5px
|
||||||
|
border 2px solid rgba($theme-color, 0.3)
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
@multiple = if @opts.multiple? then @opts.multiple else false
|
&:disabled
|
||||||
@title = @opts.title || '<i class="fa fa-file-o"></i>ファイルを選択'
|
opacity 0.7
|
||||||
|
cursor default
|
||||||
|
|
||||||
@on \mount ~>
|
.ok
|
||||||
@refs.window.refs.browser.on \selected (file) ~>
|
right 16px
|
||||||
@file = file
|
color $theme-color-foreground
|
||||||
@ok!
|
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
|
||||||
|
border solid 1px lighten($theme-color, 15%)
|
||||||
|
|
||||||
@refs.window.refs.browser.on \change-selection (files) ~>
|
&:not(:disabled)
|
||||||
@file = files
|
font-weight bold
|
||||||
@update!
|
|
||||||
|
|
||||||
@refs.window.on \closed ~>
|
&:hover:not(:disabled)
|
||||||
@unmount!
|
background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%)
|
||||||
|
border-color $theme-color
|
||||||
|
|
||||||
@close = ~>
|
&:active:not(:disabled)
|
||||||
@refs.window.close!
|
background $theme-color
|
||||||
|
border-color $theme-color
|
||||||
|
|
||||||
@upload = ~>
|
.cancel
|
||||||
@refs.window.refs.browser.select-local-file!
|
right 148px
|
||||||
|
color #888
|
||||||
|
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
|
||||||
|
border solid 1px #e2e2e2
|
||||||
|
|
||||||
@ok = ~>
|
&:hover
|
||||||
@trigger \selected @file
|
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
|
||||||
@refs.window.close!
|
border-color #dcdcdc
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background #ececec
|
||||||
|
border-color #dcdcdc
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@file = []
|
||||||
|
|
||||||
|
@multiple = if @opts.multiple? then @opts.multiple else false
|
||||||
|
@title = @opts.title || '<i class="fa fa-file-o"></i>ファイルを選択'
|
||||||
|
|
||||||
|
@on \mount ~>
|
||||||
|
@refs.window.refs.browser.on \selected (file) ~>
|
||||||
|
@file = file
|
||||||
|
@ok!
|
||||||
|
|
||||||
|
@refs.window.refs.browser.on \change-selection (files) ~>
|
||||||
|
@file = files
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@refs.window.on \closed ~>
|
||||||
|
@unmount!
|
||||||
|
|
||||||
|
@close = ~>
|
||||||
|
@refs.window.close!
|
||||||
|
|
||||||
|
@upload = ~>
|
||||||
|
@refs.window.refs.browser.select-local-file!
|
||||||
|
|
||||||
|
@ok = ~>
|
||||||
|
@trigger \selected @file
|
||||||
|
@refs.window.close!
|
||||||
|
</script>
|
||||||
|
</mk-select-file-from-drive-window>
|
||||||
|
|
|
@ -1,44 +1,46 @@
|
||||||
mk-set-avatar-suggestion(onclick={ set })
|
<mk-set-avatar-suggestion onclick="{ set }">
|
||||||
p
|
<p><b>アバターを設定</b>してみませんか?
|
||||||
b アバターを設定
|
<button onclick="{ close }"><i class="fa fa-times"></i></button>
|
||||||
| してみませんか?
|
</p>
|
||||||
button(onclick={ close }): i.fa.fa-times
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
style.
|
display block
|
||||||
display block
|
cursor pointer
|
||||||
cursor pointer
|
|
||||||
color #fff
|
|
||||||
background #a8cad0
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background #70abb5
|
|
||||||
|
|
||||||
> p
|
|
||||||
display block
|
|
||||||
margin 0 auto
|
|
||||||
padding 8px
|
|
||||||
max-width 1024px
|
|
||||||
|
|
||||||
> a
|
|
||||||
font-weight bold
|
|
||||||
color #fff
|
color #fff
|
||||||
|
background #a8cad0
|
||||||
|
|
||||||
> button
|
&:hover
|
||||||
position absolute
|
background #70abb5
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
padding 8px
|
|
||||||
color #fff
|
|
||||||
|
|
||||||
script.
|
> p
|
||||||
@mixin \i
|
display block
|
||||||
@mixin \update-avatar
|
margin 0 auto
|
||||||
|
padding 8px
|
||||||
|
max-width 1024px
|
||||||
|
|
||||||
@set = ~>
|
> a
|
||||||
@update-avatar @I, (i) ~>
|
font-weight bold
|
||||||
@update-i i
|
color #fff
|
||||||
|
|
||||||
@close = (e) ~>
|
> button
|
||||||
e.prevent-default!
|
position absolute
|
||||||
e.stop-propagation!
|
top 0
|
||||||
@unmount!
|
right 0
|
||||||
|
padding 8px
|
||||||
|
color #fff
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mixin \update-avatar
|
||||||
|
|
||||||
|
@set = ~>
|
||||||
|
@update-avatar @I, (i) ~>
|
||||||
|
@update-i i
|
||||||
|
|
||||||
|
@close = (e) ~>
|
||||||
|
e.prevent-default!
|
||||||
|
e.stop-propagation!
|
||||||
|
@unmount!
|
||||||
|
</script>
|
||||||
|
</mk-set-avatar-suggestion>
|
||||||
|
|
|
@ -1,44 +1,46 @@
|
||||||
mk-set-banner-suggestion(onclick={ set })
|
<mk-set-banner-suggestion onclick="{ set }">
|
||||||
p
|
<p><b>バナーを設定</b>してみませんか?
|
||||||
b バナーを設定
|
<button onclick="{ close }"><i class="fa fa-times"></i></button>
|
||||||
| してみませんか?
|
</p>
|
||||||
button(onclick={ close }): i.fa.fa-times
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
style.
|
display block
|
||||||
display block
|
cursor pointer
|
||||||
cursor pointer
|
|
||||||
color #fff
|
|
||||||
background #a8cad0
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background #70abb5
|
|
||||||
|
|
||||||
> p
|
|
||||||
display block
|
|
||||||
margin 0 auto
|
|
||||||
padding 8px
|
|
||||||
max-width 1024px
|
|
||||||
|
|
||||||
> a
|
|
||||||
font-weight bold
|
|
||||||
color #fff
|
color #fff
|
||||||
|
background #a8cad0
|
||||||
|
|
||||||
> button
|
&:hover
|
||||||
position absolute
|
background #70abb5
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
padding 8px
|
|
||||||
color #fff
|
|
||||||
|
|
||||||
script.
|
> p
|
||||||
@mixin \i
|
display block
|
||||||
@mixin \update-banner
|
margin 0 auto
|
||||||
|
padding 8px
|
||||||
|
max-width 1024px
|
||||||
|
|
||||||
@set = ~>
|
> a
|
||||||
@update-banner @I, (i) ~>
|
font-weight bold
|
||||||
@update-i i
|
color #fff
|
||||||
|
|
||||||
@close = (e) ~>
|
> button
|
||||||
e.prevent-default!
|
position absolute
|
||||||
e.stop-propagation!
|
top 0
|
||||||
@unmount!
|
right 0
|
||||||
|
padding 8px
|
||||||
|
color #fff
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mixin \update-banner
|
||||||
|
|
||||||
|
@set = ~>
|
||||||
|
@update-banner @I, (i) ~>
|
||||||
|
@update-i i
|
||||||
|
|
||||||
|
@close = (e) ~>
|
||||||
|
e.prevent-default!
|
||||||
|
e.stop-propagation!
|
||||||
|
@unmount!
|
||||||
|
</script>
|
||||||
|
</mk-set-banner-suggestion>
|
||||||
|
|
|
@ -1,26 +1,25 @@
|
||||||
mk-settings-window
|
<mk-settings-window>
|
||||||
mk-window@window(is-modal={ true }, width={ '700px' }, height={ '550px' })
|
<mk-window ref="window" is-modal="{ true }" width="{ '700px' }" height="{ '550px' }"><yield to="header"><i class="fa fa-cog"></i>設定</yield>
|
||||||
<yield to="header">
|
<yield to="content">
|
||||||
i.fa.fa-cog
|
<mk-settings></mk-settings></yield>
|
||||||
| 設定
|
</mk-window>
|
||||||
</yield>
|
<style type="stylus">
|
||||||
<yield to="content">
|
:scope
|
||||||
mk-settings
|
> mk-window
|
||||||
</yield>
|
[data-yield='header']
|
||||||
|
> i
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
style.
|
[data-yield='content']
|
||||||
> mk-window
|
overflow auto
|
||||||
[data-yield='header']
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
[data-yield='content']
|
</style>
|
||||||
overflow auto
|
<script>
|
||||||
|
@on \mount ~>
|
||||||
|
@refs.window.on \closed ~>
|
||||||
|
@unmount!
|
||||||
|
|
||||||
script.
|
@close = ~>
|
||||||
@on \mount ~>
|
@refs.window.close!
|
||||||
@refs.window.on \closed ~>
|
</script>
|
||||||
@unmount!
|
</mk-settings-window>
|
||||||
|
|
||||||
@close = ~>
|
|
||||||
@refs.window.close!
|
|
||||||
|
|
|
@ -1,271 +1,266 @@
|
||||||
mk-settings
|
<mk-settings>
|
||||||
div.nav
|
<div class="nav">
|
||||||
p(class={ active: page == 'account' }, onmousedown={ set-page.bind(null, 'account') })
|
<p class="{ active: page == 'account' }" onmousedown="{ setPage.bind(null, 'account') }"><i class="fa fa-fw fa-user"></i>アカウント</p>
|
||||||
i.fa.fa-fw.fa-user
|
<p class="{ active: page == 'web' }" onmousedown="{ setPage.bind(null, 'web') }"><i class="fa fa-fw fa-desktop"></i>Web</p>
|
||||||
| アカウント
|
<p class="{ active: page == 'notification' }" onmousedown="{ setPage.bind(null, 'notification') }"><i class="fa fa-fw fa-bell-o"></i>通知</p>
|
||||||
p(class={ active: page == 'web' }, onmousedown={ set-page.bind(null, 'web') })
|
<p class="{ active: page == 'drive' }" onmousedown="{ setPage.bind(null, 'drive') }"><i class="fa fa-fw fa-cloud"></i>ドライブ</p>
|
||||||
i.fa.fa-fw.fa-desktop
|
<p class="{ active: page == 'apps' }" onmousedown="{ setPage.bind(null, 'apps') }"><i class="fa fa-fw fa-puzzle-piece"></i>アプリ</p>
|
||||||
| Web
|
<p class="{ active: page == 'signin' }" onmousedown="{ setPage.bind(null, 'signin') }"><i class="fa fa-fw fa-sign-in"></i>ログイン履歴</p>
|
||||||
p(class={ active: page == 'notification' }, onmousedown={ set-page.bind(null, 'notification') })
|
<p class="{ active: page == 'password' }" onmousedown="{ setPage.bind(null, 'password') }"><i class="fa fa-fw fa-unlock-alt"></i>パスワード</p>
|
||||||
i.fa.fa-fw.fa-bell-o
|
<p class="{ active: page == 'api' }" onmousedown="{ setPage.bind(null, 'api') }"><i class="fa fa-fw fa-key"></i>API</p>
|
||||||
| 通知
|
</div>
|
||||||
p(class={ active: page == 'drive' }, onmousedown={ set-page.bind(null, 'drive') })
|
<div class="pages">
|
||||||
i.fa.fa-fw.fa-cloud
|
<section class="account" show="{ page == 'account' }">
|
||||||
| ドライブ
|
<h1>アカウント</h1>
|
||||||
p(class={ active: page == 'apps' }, onmousedown={ set-page.bind(null, 'apps') })
|
<label class="avatar">
|
||||||
i.fa.fa-fw.fa-puzzle-piece
|
<p>アバター</p><img class="avatar" src="{ I.avatar_url + '?thumbnail&size=64' }" alt="avatar"/>
|
||||||
| アプリ
|
<button class="style-normal" onclick="{ avatar }">画像を選択</button>
|
||||||
p(class={ active: page == 'signin' }, onmousedown={ set-page.bind(null, 'signin') })
|
</label>
|
||||||
i.fa.fa-fw.fa-sign-in
|
<label>
|
||||||
| ログイン履歴
|
<p>名前</p>
|
||||||
p(class={ active: page == 'password' }, onmousedown={ set-page.bind(null, 'password') })
|
<input ref="accountName" type="text" value="{ I.name }"/>
|
||||||
i.fa.fa-fw.fa-unlock-alt
|
</label>
|
||||||
| パスワード
|
<label>
|
||||||
p(class={ active: page == 'api' }, onmousedown={ set-page.bind(null, 'api') })
|
<p>場所</p>
|
||||||
i.fa.fa-fw.fa-key
|
<input ref="accountLocation" type="text" value="{ I.location }"/>
|
||||||
| API
|
</label>
|
||||||
|
<label>
|
||||||
div.pages
|
<p>自己紹介</p>
|
||||||
section.account(show={ page == 'account' })
|
<textarea ref="accountBio">{ I.bio }</textarea>
|
||||||
h1 アカウント
|
</label>
|
||||||
label.avatar
|
<label>
|
||||||
p アバター
|
<p>誕生日</p>
|
||||||
img.avatar(src={ I.avatar_url + '?thumbnail&size=64' }, alt='avatar')
|
<input ref="accountBirthday" type="date" value="{ I.birthday }"/>
|
||||||
button.style-normal(onclick={ avatar }) 画像を選択
|
</label>
|
||||||
label
|
<button class="style-primary" onclick="{ updateAccount }">保存</button>
|
||||||
p 名前
|
</section>
|
||||||
input@account-name(type='text', value={ I.name })
|
<section class="web" show="{ page == 'web' }">
|
||||||
label
|
<h1>デザイン</h1>
|
||||||
p 場所
|
<label>
|
||||||
input@account-location(type='text', value={ I.location })
|
<p>壁紙</p>
|
||||||
label
|
<button class="style-normal" onclick="{ wallpaper }">画像を選択</button>
|
||||||
p 自己紹介
|
</label>
|
||||||
textarea@account-bio { I.bio }
|
</section>
|
||||||
label
|
<section class="web" show="{ page == 'web' }">
|
||||||
p 誕生日
|
<h1>その他</h1>
|
||||||
input@account-birthday(type='date', value={ I.birthday })
|
<label class="checkbox">
|
||||||
button.style-primary(onclick={ update-account }) 保存
|
<input type="checkbox" checked="{ I.data.cache }" onclick="{ updateCache }"/>
|
||||||
|
<p>読み込みを高速化する</p>
|
||||||
section.web(show={ page == 'web' })
|
<p>API通信時に新鮮なユーザー情報をキャッシュすることでフェッチのオーバーヘッドを無くします。(実験的)</p>
|
||||||
h1 デザイン
|
</label>
|
||||||
label
|
<label class="checkbox">
|
||||||
p 壁紙
|
<input type="checkbox" checked="{ I.data.debug }" onclick="{ updateDebug }"/>
|
||||||
button.style-normal(onclick={ wallpaper }) 画像を選択
|
<p>開発者モード</p>
|
||||||
section.web(show={ page == 'web' })
|
<p>デバッグ等の開発者モードを有効にします。</p>
|
||||||
h1 その他
|
</label>
|
||||||
label.checkbox
|
<label class="checkbox">
|
||||||
input(type='checkbox', checked={ I.data.cache }, onclick={ update-cache })
|
<input type="checkbox" checked="{ I.data.nya }" onclick="{ updateNya }"/>
|
||||||
p 読み込みを高速化する
|
<p><i>な</i>を<i>にゃ</i>に変換する</p>
|
||||||
p API通信時に新鮮なユーザー情報をキャッシュすることでフェッチのオーバーヘッドを無くします。(実験的)
|
<p>攻撃的な投稿が多少和らぐ可能性があります。</p>
|
||||||
label.checkbox
|
</label>
|
||||||
input(type='checkbox', checked={ I.data.debug }, onclick={ update-debug })
|
</section>
|
||||||
p 開発者モード
|
<section class="signin" show="{ page == 'signin' }">
|
||||||
p デバッグ等の開発者モードを有効にします。
|
<h1>ログイン履歴</h1>
|
||||||
label.checkbox
|
<mk-signin-history></mk-signin-history>
|
||||||
input(type='checkbox', checked={ I.data.nya }, onclick={ update-nya })
|
</section>
|
||||||
p <i>な</i>を<i>にゃ</i>に変換する
|
<section class="api" show="{ page == 'api' }">
|
||||||
p 攻撃的な投稿が多少和らぐ可能性があります。
|
<h1>API</h1>
|
||||||
|
<p>Token:<code>{ I.token }</code></p>
|
||||||
section.signin(show={ page == 'signin' })
|
<p>APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。</p>
|
||||||
h1 ログイン履歴
|
<p>アカウントを乗っ取られてしまう可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。</p>
|
||||||
mk-signin-history
|
<p>万が一このトークンが漏れたりその可能性がある場合は
|
||||||
|
<button class="regenerate" onclick="{ regenerateToken }">トークンを再生成</button>できます。(副作用として、ログインしているすべてのデバイスでログアウトが発生します)
|
||||||
section.api(show={ page == 'api' })
|
</p>
|
||||||
h1 API
|
</section>
|
||||||
p
|
</div>
|
||||||
| Token:
|
<style type="stylus">
|
||||||
code { I.token }
|
:scope
|
||||||
p APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。
|
|
||||||
p アカウントを乗っ取られてしまう可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。
|
|
||||||
p
|
|
||||||
| 万が一このトークンが漏れたりその可能性がある場合は
|
|
||||||
button.regenerate(onclick={ regenerate-token }) トークンを再生成
|
|
||||||
| できます。(副作用として、ログインしているすべてのデバイスでログアウトが発生します)
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
|
|
||||||
input:not([type])
|
|
||||||
input[type='text']
|
|
||||||
input[type='password']
|
|
||||||
input[type='email']
|
|
||||||
textarea
|
|
||||||
padding 8px
|
|
||||||
width 100%
|
|
||||||
font-size 16px
|
|
||||||
color #55595c
|
|
||||||
border solid 1px #dadada
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
border-color #aeaeae
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
border-color #aeaeae
|
|
||||||
|
|
||||||
> .nav
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
width 200px
|
|
||||||
height 100%
|
|
||||||
padding 16px 0 0 0
|
|
||||||
border-right solid 1px #ddd
|
|
||||||
|
|
||||||
> p
|
|
||||||
display block
|
display block
|
||||||
padding 10px 16px
|
|
||||||
margin 0
|
|
||||||
color #666
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
-ms-user-select none
|
input:not([type])
|
||||||
-moz-user-select none
|
input[type='text']
|
||||||
-webkit-user-select none
|
input[type='password']
|
||||||
user-select none
|
input[type='email']
|
||||||
|
textarea
|
||||||
|
padding 8px
|
||||||
|
width 100%
|
||||||
|
font-size 16px
|
||||||
|
color #55595c
|
||||||
|
border solid 1px #dadada
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
transition margin-left 0.2s ease
|
&:hover
|
||||||
|
border-color #aeaeae
|
||||||
|
|
||||||
> i
|
&:focus
|
||||||
margin-right 4px
|
border-color #aeaeae
|
||||||
|
|
||||||
&:hover
|
> .nav
|
||||||
color #555
|
position absolute
|
||||||
|
top 0
|
||||||
&.active
|
left 0
|
||||||
margin-left 8px
|
width 200px
|
||||||
color $theme-color !important
|
height 100%
|
||||||
|
padding 16px 0 0 0
|
||||||
> .pages
|
border-right solid 1px #ddd
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
left 200px
|
|
||||||
width calc(100% - 200px)
|
|
||||||
|
|
||||||
> section
|
|
||||||
padding 32px
|
|
||||||
|
|
||||||
// & + section
|
|
||||||
// margin-top 16px
|
|
||||||
|
|
||||||
h1
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0 0 8px 0
|
|
||||||
font-size 1em
|
|
||||||
color #555
|
|
||||||
border-bottom solid 1px #eee
|
|
||||||
|
|
||||||
label
|
|
||||||
display block
|
|
||||||
margin 16px 0
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
> p
|
> p
|
||||||
margin 0 0 8px 0
|
display block
|
||||||
font-weight bold
|
padding 10px 16px
|
||||||
color #373a3c
|
margin 0
|
||||||
|
color #666
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
&.checkbox
|
-ms-user-select none
|
||||||
> input
|
-moz-user-select none
|
||||||
position absolute
|
-webkit-user-select none
|
||||||
top 0
|
user-select none
|
||||||
left 0
|
|
||||||
|
|
||||||
&:checked + p
|
transition margin-left 0.2s ease
|
||||||
color $theme-color
|
|
||||||
|
|
||||||
> p
|
> i
|
||||||
width calc(100% - 32px)
|
margin-right 4px
|
||||||
margin 0 0 0 32px
|
|
||||||
font-weight bold
|
|
||||||
|
|
||||||
&:last-child
|
|
||||||
font-weight normal
|
|
||||||
color #999
|
|
||||||
|
|
||||||
&.account
|
|
||||||
> .general
|
|
||||||
> .avatar
|
|
||||||
> img
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
width 64px
|
|
||||||
height 64px
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
> button
|
|
||||||
float left
|
|
||||||
margin-left 8px
|
|
||||||
|
|
||||||
&.api
|
|
||||||
code
|
|
||||||
padding 4px
|
|
||||||
background #eee
|
|
||||||
|
|
||||||
.regenerate
|
|
||||||
display inline
|
|
||||||
color $theme-color
|
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
text-decoration underline
|
color #555
|
||||||
|
|
||||||
script.
|
&.active
|
||||||
@mixin \i
|
margin-left 8px
|
||||||
@mixin \api
|
color $theme-color !important
|
||||||
@mixin \dialog
|
|
||||||
@mixin \update-avatar
|
|
||||||
@mixin \update-wallpaper
|
|
||||||
|
|
||||||
@page = \account
|
> .pages
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 200px
|
||||||
|
width calc(100% - 200px)
|
||||||
|
|
||||||
@set-page = (page) ~>
|
> section
|
||||||
@page = page
|
padding 32px
|
||||||
|
|
||||||
@avatar = ~>
|
// & + section
|
||||||
@update-avatar @I, (i) ~>
|
// margin-top 16px
|
||||||
@update-i i
|
|
||||||
|
|
||||||
@wallpaper = ~>
|
h1
|
||||||
@update-wallpaper @I, (i) ~>
|
display block
|
||||||
@update-i i
|
margin 0
|
||||||
|
padding 0 0 8px 0
|
||||||
|
font-size 1em
|
||||||
|
color #555
|
||||||
|
border-bottom solid 1px #eee
|
||||||
|
|
||||||
@update-account = ~>
|
label
|
||||||
@api \i/update do
|
display block
|
||||||
name: @refs.account-name.value
|
margin 16px 0
|
||||||
location: @refs.account-location.value
|
|
||||||
bio: @refs.account-bio.value
|
|
||||||
birthday: @refs.account-birthday.value
|
|
||||||
.then (i) ~>
|
|
||||||
@update-i i
|
|
||||||
alert \ok
|
|
||||||
.catch (err) ~>
|
|
||||||
console.error err
|
|
||||||
|
|
||||||
@update-cache = ~>
|
&:after
|
||||||
@I.data.cache = !@I.data.cache
|
content ""
|
||||||
@api \i/appdata/set do
|
display block
|
||||||
data: JSON.stringify do
|
clear both
|
||||||
cache: @I.data.cache
|
|
||||||
.then ~>
|
|
||||||
@update-i!
|
|
||||||
|
|
||||||
@update-debug = ~>
|
> p
|
||||||
@I.data.debug = !@I.data.debug
|
margin 0 0 8px 0
|
||||||
@api \i/appdata/set do
|
font-weight bold
|
||||||
data: JSON.stringify do
|
color #373a3c
|
||||||
debug: @I.data.debug
|
|
||||||
.then ~>
|
|
||||||
@update-i!
|
|
||||||
|
|
||||||
@update-nya = ~>
|
&.checkbox
|
||||||
@I.data.nya = !@I.data.nya
|
> input
|
||||||
@api \i/appdata/set do
|
position absolute
|
||||||
data: JSON.stringify do
|
top 0
|
||||||
nya: @I.data.nya
|
left 0
|
||||||
.then ~>
|
|
||||||
@update-i!
|
&:checked + p
|
||||||
|
color $theme-color
|
||||||
|
|
||||||
|
> p
|
||||||
|
width calc(100% - 32px)
|
||||||
|
margin 0 0 0 32px
|
||||||
|
font-weight bold
|
||||||
|
|
||||||
|
&:last-child
|
||||||
|
font-weight normal
|
||||||
|
color #999
|
||||||
|
|
||||||
|
&.account
|
||||||
|
> .general
|
||||||
|
> .avatar
|
||||||
|
> img
|
||||||
|
display block
|
||||||
|
float left
|
||||||
|
width 64px
|
||||||
|
height 64px
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
|
> button
|
||||||
|
float left
|
||||||
|
margin-left 8px
|
||||||
|
|
||||||
|
&.api
|
||||||
|
code
|
||||||
|
padding 4px
|
||||||
|
background #eee
|
||||||
|
|
||||||
|
.regenerate
|
||||||
|
display inline
|
||||||
|
color $theme-color
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
text-decoration underline
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mixin \api
|
||||||
|
@mixin \dialog
|
||||||
|
@mixin \update-avatar
|
||||||
|
@mixin \update-wallpaper
|
||||||
|
|
||||||
|
@page = \account
|
||||||
|
|
||||||
|
@set-page = (page) ~>
|
||||||
|
@page = page
|
||||||
|
|
||||||
|
@avatar = ~>
|
||||||
|
@update-avatar @I, (i) ~>
|
||||||
|
@update-i i
|
||||||
|
|
||||||
|
@wallpaper = ~>
|
||||||
|
@update-wallpaper @I, (i) ~>
|
||||||
|
@update-i i
|
||||||
|
|
||||||
|
@update-account = ~>
|
||||||
|
@api \i/update do
|
||||||
|
name: @refs.account-name.value
|
||||||
|
location: @refs.account-location.value
|
||||||
|
bio: @refs.account-bio.value
|
||||||
|
birthday: @refs.account-birthday.value
|
||||||
|
.then (i) ~>
|
||||||
|
@update-i i
|
||||||
|
alert \ok
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
|
@update-cache = ~>
|
||||||
|
@I.data.cache = !@I.data.cache
|
||||||
|
@api \i/appdata/set do
|
||||||
|
data: JSON.stringify do
|
||||||
|
cache: @I.data.cache
|
||||||
|
.then ~>
|
||||||
|
@update-i!
|
||||||
|
|
||||||
|
@update-debug = ~>
|
||||||
|
@I.data.debug = !@I.data.debug
|
||||||
|
@api \i/appdata/set do
|
||||||
|
data: JSON.stringify do
|
||||||
|
debug: @I.data.debug
|
||||||
|
.then ~>
|
||||||
|
@update-i!
|
||||||
|
|
||||||
|
@update-nya = ~>
|
||||||
|
@I.data.nya = !@I.data.nya
|
||||||
|
@api \i/appdata/set do
|
||||||
|
data: JSON.stringify do
|
||||||
|
nya: @I.data.nya
|
||||||
|
.then ~>
|
||||||
|
@update-i!
|
||||||
|
</script>
|
||||||
|
</mk-settings>
|
||||||
|
|
|
@ -1,73 +1,75 @@
|
||||||
mk-signin-history
|
<mk-signin-history>
|
||||||
div.records(if={ history.length != 0 })
|
<div class="records" if="{ history.length != 0 }">
|
||||||
div(each={ history })
|
<div each="{ history }">
|
||||||
mk-time(time={ created_at })
|
<mk-time time="{ created_at }"></mk-time>
|
||||||
header
|
<header><i class="fa fa-check" if="{ success }"></i><i class="fa fa-times" if="{ !success }"></i><span class="ip">{ ip }</span></header>
|
||||||
i.fa.fa-check(if={ success })
|
<pre><code>{ JSON.stringify(headers, null, ' ') }</code></pre>
|
||||||
i.fa.fa-times(if={ !success })
|
</div>
|
||||||
span.ip { ip }
|
</div>
|
||||||
pre: code { JSON.stringify(headers, null, ' ') }
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display block
|
||||||
|
|
||||||
style.
|
> .records
|
||||||
display block
|
> div
|
||||||
|
padding 16px 0 0 0
|
||||||
|
border-bottom solid 1px #eee
|
||||||
|
|
||||||
> .records
|
> header
|
||||||
> div
|
|
||||||
padding 16px 0 0 0
|
|
||||||
border-bottom solid 1px #eee
|
|
||||||
|
|
||||||
> header
|
> i
|
||||||
|
margin-right 8px
|
||||||
|
|
||||||
> i
|
&.fa-check
|
||||||
margin-right 8px
|
color #0fda82
|
||||||
|
|
||||||
&.fa-check
|
&.fa-times
|
||||||
color #0fda82
|
color #ff3100
|
||||||
|
|
||||||
&.fa-times
|
> .ip
|
||||||
color #ff3100
|
display inline-block
|
||||||
|
color #444
|
||||||
|
background #f8f8f8
|
||||||
|
|
||||||
> .ip
|
> mk-time
|
||||||
display inline-block
|
position absolute
|
||||||
color #444
|
top 16px
|
||||||
background #f8f8f8
|
right 0
|
||||||
|
color #777
|
||||||
|
|
||||||
> mk-time
|
> pre
|
||||||
position absolute
|
overflow auto
|
||||||
top 16px
|
max-height 100px
|
||||||
right 0
|
|
||||||
color #777
|
|
||||||
|
|
||||||
> pre
|
> code
|
||||||
overflow auto
|
white-space pre-wrap
|
||||||
max-height 100px
|
word-break break-all
|
||||||
|
color #4a535a
|
||||||
|
|
||||||
> code
|
</style>
|
||||||
white-space pre-wrap
|
<script>
|
||||||
word-break break-all
|
@mixin \api
|
||||||
color #4a535a
|
@mixin \stream
|
||||||
|
|
||||||
script.
|
@history = []
|
||||||
@mixin \api
|
@fetching = true
|
||||||
@mixin \stream
|
|
||||||
|
|
||||||
@history = []
|
@on \mount ~>
|
||||||
@fetching = true
|
@api \i/signin_history
|
||||||
|
.then (history) ~>
|
||||||
|
@history = history
|
||||||
|
@fetching = false
|
||||||
|
@update!
|
||||||
|
.catch (err) ~>
|
||||||
|
console.error err
|
||||||
|
|
||||||
@on \mount ~>
|
@stream.on \signin @on-signin
|
||||||
@api \i/signin_history
|
|
||||||
.then (history) ~>
|
@on \unmount ~>
|
||||||
@history = history
|
@stream.off \signin @on-signin
|
||||||
@fetching = false
|
|
||||||
|
@on-signin = (signin) ~>
|
||||||
|
@history.unshift signin
|
||||||
@update!
|
@update!
|
||||||
.catch (err) ~>
|
</script>
|
||||||
console.error err
|
</mk-signin-history>
|
||||||
|
|
||||||
@stream.on \signin @on-signin
|
|
||||||
|
|
||||||
@on \unmount ~>
|
|
||||||
@stream.off \signin @on-signin
|
|
||||||
|
|
||||||
@on-signin = (signin) ~>
|
|
||||||
@history.unshift signin
|
|
||||||
@update!
|
|
||||||
|
|
|
@ -1,59 +1,54 @@
|
||||||
mk-stream-indicator
|
<mk-stream-indicator>
|
||||||
p(if={ state == 'initializing' })
|
<p if="{ state == 'initializing' }"><i class="fa fa-spinner fa-spin"></i><span>接続中
|
||||||
i.fa.fa-spinner.fa-spin
|
<mk-ellipsis></mk-ellipsis></span></p>
|
||||||
span
|
<p if="{ state == 'reconnecting' }"><i class="fa fa-spinner fa-spin"></i><span>切断されました 接続中
|
||||||
| 接続中
|
<mk-ellipsis></mk-ellipsis></span></p>
|
||||||
mk-ellipsis
|
<p if="{ state == 'connected' }"><i class="fa fa-check"></i><span>接続完了</span></p>
|
||||||
p(if={ state == 'reconnecting' })
|
<style type="stylus">
|
||||||
i.fa.fa-spinner.fa-spin
|
:scope
|
||||||
span
|
display block
|
||||||
| 切断されました 接続中
|
pointer-events none
|
||||||
mk-ellipsis
|
position fixed
|
||||||
p(if={ state == 'connected' })
|
z-index 16384
|
||||||
i.fa.fa-check
|
bottom 8px
|
||||||
span 接続完了
|
right 8px
|
||||||
|
margin 0
|
||||||
|
padding 6px 12px
|
||||||
|
font-size 0.9em
|
||||||
|
color #fff
|
||||||
|
background rgba(0, 0, 0, 0.8)
|
||||||
|
|
||||||
style.
|
> p
|
||||||
display block
|
display block
|
||||||
pointer-events none
|
margin 0
|
||||||
position fixed
|
|
||||||
z-index 16384
|
|
||||||
bottom 8px
|
|
||||||
right 8px
|
|
||||||
margin 0
|
|
||||||
padding 6px 12px
|
|
||||||
font-size 0.9em
|
|
||||||
color #fff
|
|
||||||
background rgba(0, 0, 0, 0.8)
|
|
||||||
|
|
||||||
> p
|
> i
|
||||||
display block
|
margin-right 0.25em
|
||||||
margin 0
|
|
||||||
|
|
||||||
> i
|
</style>
|
||||||
margin-right 0.25em
|
<script>
|
||||||
|
@mixin \stream
|
||||||
|
|
||||||
script.
|
@on \before-mount ~>
|
||||||
@mixin \stream
|
@state = @get-stream-state!
|
||||||
|
|
||||||
@on \before-mount ~>
|
if @state == \connected
|
||||||
@state = @get-stream-state!
|
@root.style.opacity = 0
|
||||||
|
|
||||||
if @state == \connected
|
@stream-state-ev.on \connected ~>
|
||||||
@root.style.opacity = 0
|
@state = @get-stream-state!
|
||||||
|
@update!
|
||||||
|
set-timeout ~>
|
||||||
|
Velocity @root, {
|
||||||
|
opacity: 0
|
||||||
|
} 200ms \linear
|
||||||
|
, 1000ms
|
||||||
|
|
||||||
@stream-state-ev.on \connected ~>
|
@stream-state-ev.on \closed ~>
|
||||||
@state = @get-stream-state!
|
@state = @get-stream-state!
|
||||||
@update!
|
@update!
|
||||||
set-timeout ~>
|
|
||||||
Velocity @root, {
|
Velocity @root, {
|
||||||
opacity: 0
|
opacity: 1
|
||||||
} 200ms \linear
|
} 0ms
|
||||||
, 1000ms
|
</script>
|
||||||
|
</mk-stream-indicator>
|
||||||
@stream-state-ev.on \closed ~>
|
|
||||||
@state = @get-stream-state!
|
|
||||||
@update!
|
|
||||||
Velocity @root, {
|
|
||||||
opacity: 1
|
|
||||||
} 0ms
|
|
||||||
|
|
|
@ -1,37 +1,38 @@
|
||||||
mk-sub-post-content
|
<mk-sub-post-content>
|
||||||
div.body
|
<div class="body"><a class="reply" if="{ post.reply_to_id }"><i class="fa fa-reply"></i></a><span ref="text"></span><a class="quote" if="{ post.repost_id }" href="{ '/post:' + post.repost_id }">RP: ...</a></div>
|
||||||
a.reply(if={ post.reply_to_id }): i.fa.fa-reply
|
<details if="{ post.media }">
|
||||||
span@text
|
<summary>({ post.media.length }枚の画像)</summary>
|
||||||
a.quote(if={ post.repost_id }, href={ '/post:' + post.repost_id }) RP: ...
|
<mk-images-viewer images="{ post.media }"></mk-images-viewer>
|
||||||
details(if={ post.media })
|
</details>
|
||||||
summary ({ post.media.length }枚の画像)
|
<style type="stylus">
|
||||||
mk-images-viewer(images={ post.media })
|
:scope
|
||||||
|
display block
|
||||||
|
word-wrap break-word
|
||||||
|
|
||||||
style.
|
> .body
|
||||||
display block
|
> .reply
|
||||||
word-wrap break-word
|
margin-right 6px
|
||||||
|
color #717171
|
||||||
|
|
||||||
> .body
|
> .quote
|
||||||
> .reply
|
margin-left 4px
|
||||||
margin-right 6px
|
font-style oblique
|
||||||
color #717171
|
color #a0bf46
|
||||||
|
|
||||||
> .quote
|
</style>
|
||||||
margin-left 4px
|
<script>
|
||||||
font-style oblique
|
@mixin \text
|
||||||
color #a0bf46
|
@mixin \user-preview
|
||||||
|
|
||||||
script.
|
@post = @opts.post
|
||||||
@mixin \text
|
|
||||||
@mixin \user-preview
|
|
||||||
|
|
||||||
@post = @opts.post
|
@on \mount ~>
|
||||||
|
if @post.text?
|
||||||
|
tokens = @analyze @post.text
|
||||||
|
@refs.text.innerHTML = @compile tokens, false
|
||||||
|
|
||||||
@on \mount ~>
|
@refs.text.children.for-each (e) ~>
|
||||||
if @post.text?
|
if e.tag-name == \MK-URL
|
||||||
tokens = @analyze @post.text
|
riot.mount e
|
||||||
@refs.text.innerHTML = @compile tokens, false
|
</script>
|
||||||
|
</mk-sub-post-content>
|
||||||
@refs.text.children.for-each (e) ~>
|
|
||||||
if e.tag-name == \MK-URL
|
|
||||||
riot.mount e
|
|
||||||
|
|
|
@ -1,95 +1,99 @@
|
||||||
mk-timeline-post-sub(title={ title })
|
<mk-timeline-post-sub title="{ title }">
|
||||||
article
|
<article><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar" data-user-preview="{ post.user_id }"/></a>
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username })
|
<div class="main">
|
||||||
img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ post.user_id })
|
<header><a class="name" href="{ CONFIG.url + '/' + post.user.username }" data-user-preview="{ post.user_id }">{ post.user.name }</a><span class="username">@{ post.user.username }</span><a class="created-at" href="{ CONFIG.url + '/' + post.user.username + '/' + post.id }">
|
||||||
div.main
|
<mk-time time="{ post.created_at }"></mk-time></a></header>
|
||||||
header
|
<div class="body">
|
||||||
a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id })
|
<mk-sub-post-content class="text" post="{ post }"></mk-sub-post-content>
|
||||||
| { post.user.name }
|
</div>
|
||||||
span.username
|
</div>
|
||||||
| @{ post.user.username }
|
</article>
|
||||||
a.created-at(href={ CONFIG.url + '/' + post.user.username + '/' + post.id })
|
<script>
|
||||||
mk-time(time={ post.created_at })
|
@mixin \date-stringify
|
||||||
div.body
|
@mixin \user-preview
|
||||||
mk-sub-post-content.text(post={ post })
|
|
||||||
|
|
||||||
script.
|
@post = @opts.post
|
||||||
@mixin \date-stringify
|
|
||||||
@mixin \user-preview
|
|
||||||
|
|
||||||
@post = @opts.post
|
@title = @date-stringify @post.created_at
|
||||||
|
|
||||||
@title = @date-stringify @post.created_at
|
</script>
|
||||||
|
<style type="stylus">
|
||||||
style.
|
:scope
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
font-size 0.9em
|
|
||||||
|
|
||||||
> article
|
|
||||||
padding 16px
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
display block
|
||||||
clear both
|
margin 0
|
||||||
|
padding 0
|
||||||
|
font-size 0.9em
|
||||||
|
|
||||||
&:hover
|
> article
|
||||||
> .main > footer > button
|
padding 16px
|
||||||
color #888
|
|
||||||
|
|
||||||
> .avatar-anchor
|
&:after
|
||||||
display block
|
content ""
|
||||||
float left
|
display block
|
||||||
margin 0 14px 0 0
|
clear both
|
||||||
|
|
||||||
> .avatar
|
&:hover
|
||||||
display block
|
> .main > footer > button
|
||||||
width 52px
|
color #888
|
||||||
height 52px
|
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .main
|
> .avatar-anchor
|
||||||
float left
|
display block
|
||||||
width calc(100% - 66px)
|
float left
|
||||||
|
margin 0 14px 0 0
|
||||||
|
|
||||||
> header
|
> .avatar
|
||||||
margin-bottom 4px
|
display block
|
||||||
white-space nowrap
|
width 52px
|
||||||
line-height 21px
|
height 52px
|
||||||
|
margin 0
|
||||||
|
border-radius 8px
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
> .name
|
> .main
|
||||||
display inline
|
float left
|
||||||
margin 0
|
width calc(100% - 66px)
|
||||||
padding 0
|
|
||||||
color #607073
|
|
||||||
font-size 1em
|
|
||||||
font-weight 700
|
|
||||||
text-align left
|
|
||||||
text-decoration none
|
|
||||||
|
|
||||||
&:hover
|
> header
|
||||||
text-decoration underline
|
margin-bottom 4px
|
||||||
|
white-space nowrap
|
||||||
|
line-height 21px
|
||||||
|
|
||||||
> .username
|
> .name
|
||||||
text-align left
|
display inline
|
||||||
margin 0 0 0 8px
|
margin 0
|
||||||
color #d1d8da
|
padding 0
|
||||||
|
color #607073
|
||||||
|
font-size 1em
|
||||||
|
font-weight 700
|
||||||
|
text-align left
|
||||||
|
text-decoration none
|
||||||
|
|
||||||
> .created-at
|
&:hover
|
||||||
position absolute
|
text-decoration underline
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
color #b2b8bb
|
|
||||||
|
|
||||||
> .body
|
> .username
|
||||||
|
text-align left
|
||||||
|
margin 0 0 0 8px
|
||||||
|
color #d1d8da
|
||||||
|
|
||||||
> .text
|
> .created-at
|
||||||
cursor default
|
position absolute
|
||||||
margin 0
|
top 0
|
||||||
padding 0
|
right 0
|
||||||
font-size 1.1em
|
color #b2b8bb
|
||||||
color #717171
|
|
||||||
|
> .body
|
||||||
|
|
||||||
|
> .text
|
||||||
|
cursor default
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
font-size 1.1em
|
||||||
|
color #717171
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</mk-timeline-post-sub>
|
||||||
|
|
|
@ -1,376 +1,332 @@
|
||||||
mk-timeline-post(tabindex='-1', title={ title }, onkeydown={ on-key-down })
|
<mk-timeline-post tabindex="-1" title="{ title }" onkeydown="{ onKeyDown }">
|
||||||
|
<div class="reply-to" if="{ p.reply_to }">
|
||||||
div.reply-to(if={ p.reply_to })
|
<mk-timeline-post-sub post="{ p.reply_to }"></mk-timeline-post-sub>
|
||||||
mk-timeline-post-sub(post={ p.reply_to })
|
</div>
|
||||||
|
<div class="repost" if="{ isRepost }">
|
||||||
div.repost(if={ is-repost })
|
<p><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }" data-user-preview="{ post.user_id }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&size=32' }" alt="avatar"/></a><i class="fa fa-retweet"></i><a class="name" href="{ CONFIG.url + '/' + post.user.username }" data-user-preview="{ post.user_id }">{ post.user.name }</a>がRepost</p>
|
||||||
p
|
<mk-time time="{ post.created_at }"></mk-time>
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id }): img.avatar(src={ post.user.avatar_url + '?thumbnail&size=32' }, alt='avatar')
|
</div>
|
||||||
i.fa.fa-retweet
|
<article><a class="avatar-anchor" href="{ CONFIG.url + '/' + p.user.username }"><img class="avatar" src="{ p.user.avatar_url + '?thumbnail&size=64' }" alt="avatar" data-user-preview="{ p.user.id }"/></a>
|
||||||
a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id }) { post.user.name }
|
<div class="main">
|
||||||
| がRepost
|
<header><a class="name" href="{ CONFIG.url + '/' + p.user.username }" data-user-preview="{ p.user.id }">{ p.user.name }</a><span class="username">@{ p.user.username }</span><a class="created-at" href="{ url }">
|
||||||
mk-time(time={ post.created_at })
|
<mk-time time="{ p.created_at }"></mk-time></a></header>
|
||||||
|
<div class="body">
|
||||||
article
|
<div class="text"><a class="reply" if="{ p.reply_to }"><i class="fa fa-reply"></i></a><span ref="text"></span><a class="quote" if="{ p.repost != null }">RP:</a></div>
|
||||||
a.avatar-anchor(href={ CONFIG.url + '/' + p.user.username })
|
<div class="media" if="{ p.media }">
|
||||||
img.avatar(src={ p.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ p.user.id })
|
<mk-images-viewer images="{ p.media }"></mk-images-viewer>
|
||||||
div.main
|
</div>
|
||||||
header
|
<div class="repost" if="{ p.repost }"><i class="fa fa-quote-right fa-flip-horizontal"></i>
|
||||||
a.name(href={ CONFIG.url + '/' + p.user.username }, data-user-preview={ p.user.id })
|
<mk-post-preview class="repost" post="{ p.repost }"></mk-post-preview>
|
||||||
| { p.user.name }
|
</div>
|
||||||
span.username
|
</div>
|
||||||
| @{ p.user.username }
|
<footer>
|
||||||
a.created-at(href={ url })
|
<button onclick="{ reply }" title="返信"><i class="fa fa-reply"></i>
|
||||||
mk-time(time={ p.created_at })
|
<p class="count" if="{ p.replies_count > 0 }">{ p.replies_count }</p>
|
||||||
div.body
|
</button>
|
||||||
div.text
|
<button onclick="{ repost }" title="Repost"><i class="fa fa-retweet"></i>
|
||||||
a.reply(if={ p.reply_to }): i.fa.fa-reply
|
<p class="count" if="{ p.repost_count > 0 }">{ p.repost_count }</p>
|
||||||
span@text
|
</button>
|
||||||
a.quote(if={ p.repost != null }) RP:
|
<button class="{ liked: p.is_liked }" onclick="{ like }" title="善哉"><i class="fa fa-thumbs-o-up"></i>
|
||||||
div.media(if={ p.media })
|
<p class="count" if="{ p.likes_count > 0 }">{ p.likes_count }</p>
|
||||||
mk-images-viewer(images={ p.media })
|
</button>
|
||||||
div.repost(if={ p.repost })
|
<button onclick="{ NotImplementedException }"><i class="fa fa-ellipsis-h"></i></button>
|
||||||
i.fa.fa-quote-right.fa-flip-horizontal
|
<button onclick="{ toggleDetail }" title="詳細"><i class="fa fa-caret-down" if="{ !isDetailOpened }"></i><i class="fa fa-caret-up" if="{ isDetailOpened }"></i></button>
|
||||||
mk-post-preview.repost(post={ p.repost })
|
</footer>
|
||||||
footer
|
</div>
|
||||||
button(onclick={ reply }, title='返信')
|
</article>
|
||||||
i.fa.fa-reply
|
<div class="detail" if="{ isDetailOpened }">
|
||||||
p.count(if={ p.replies_count > 0 }) { p.replies_count }
|
<mk-post-status-graph width="462" height="130" post="{ p }"></mk-post-status-graph>
|
||||||
button(onclick={ repost }, title='Repost')
|
</div>
|
||||||
i.fa.fa-retweet
|
<style type="stylus">
|
||||||
p.count(if={ p.repost_count > 0 }) { p.repost_count }
|
:scope
|
||||||
button(class={ liked: p.is_liked }, onclick={ like }, title='善哉')
|
display block
|
||||||
i.fa.fa-thumbs-o-up
|
|
||||||
p.count(if={ p.likes_count > 0 }) { p.likes_count }
|
|
||||||
button(onclick={ NotImplementedException }): i.fa.fa-ellipsis-h
|
|
||||||
button(onclick={ toggle-detail }, title='詳細')
|
|
||||||
i.fa.fa-caret-down(if={ !is-detail-opened })
|
|
||||||
i.fa.fa-caret-up(if={ is-detail-opened })
|
|
||||||
div.detail(if={ is-detail-opened })
|
|
||||||
mk-post-status-graph(width='462', height='130', post={ p })
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
z-index 1
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
|
||||||
top 2px
|
|
||||||
right 2px
|
|
||||||
bottom 2px
|
|
||||||
left 2px
|
|
||||||
border 2px solid rgba($theme-color, 0.3)
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
> .repost
|
|
||||||
color #9dbb00
|
|
||||||
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
|
|
||||||
|
|
||||||
> p
|
|
||||||
margin 0
|
margin 0
|
||||||
padding 16px 32px
|
padding 0
|
||||||
line-height 28px
|
background #fff
|
||||||
|
|
||||||
.avatar-anchor
|
&:focus
|
||||||
display inline-block
|
z-index 1
|
||||||
|
|
||||||
.avatar
|
&:after
|
||||||
vertical-align bottom
|
content ""
|
||||||
width 28px
|
pointer-events none
|
||||||
height 28px
|
|
||||||
margin 0 8px 0 0
|
|
||||||
border-radius 6px
|
|
||||||
|
|
||||||
i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
.name
|
|
||||||
font-weight bold
|
|
||||||
|
|
||||||
> mk-time
|
|
||||||
position absolute
|
|
||||||
top 16px
|
|
||||||
right 32px
|
|
||||||
font-size 0.9em
|
|
||||||
line-height 28px
|
|
||||||
|
|
||||||
& + article
|
|
||||||
padding-top 8px
|
|
||||||
|
|
||||||
> .reply-to
|
|
||||||
padding 0 16px
|
|
||||||
background rgba(0, 0, 0, 0.0125)
|
|
||||||
|
|
||||||
> mk-post-preview
|
|
||||||
background transparent
|
|
||||||
|
|
||||||
> article
|
|
||||||
padding 28px 32px 18px 32px
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
> .main > footer > button
|
|
||||||
color #888
|
|
||||||
|
|
||||||
> .avatar-anchor
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
margin 0 16px 0 0
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
width 58px
|
|
||||||
height 58px
|
|
||||||
margin 0
|
|
||||||
border-radius 8px
|
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .main
|
|
||||||
float left
|
|
||||||
width calc(100% - 74px)
|
|
||||||
|
|
||||||
> header
|
|
||||||
margin-bottom 4px
|
|
||||||
white-space nowrap
|
|
||||||
line-height 24px
|
|
||||||
|
|
||||||
> .name
|
|
||||||
display inline
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
color #777
|
|
||||||
font-size 1em
|
|
||||||
font-weight 700
|
|
||||||
text-align left
|
|
||||||
text-decoration none
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
> .username
|
|
||||||
text-align left
|
|
||||||
margin 0 0 0 8px
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
> .created-at
|
|
||||||
position absolute
|
position absolute
|
||||||
top 0
|
top 2px
|
||||||
right 0
|
right 2px
|
||||||
font-size 0.9em
|
bottom 2px
|
||||||
color #c0c0c0
|
left 2px
|
||||||
|
border 2px solid rgba($theme-color, 0.3)
|
||||||
|
border-radius 4px
|
||||||
|
|
||||||
> .body
|
> .repost
|
||||||
|
color #9dbb00
|
||||||
|
background linear-gradient(to bottom, #edfde2 0%, #fff 100%)
|
||||||
|
|
||||||
> .text
|
> p
|
||||||
cursor default
|
|
||||||
display block
|
|
||||||
margin 0
|
margin 0
|
||||||
padding 0
|
padding 16px 32px
|
||||||
word-wrap break-word
|
line-height 28px
|
||||||
font-size 1.1em
|
|
||||||
color #717171
|
|
||||||
|
|
||||||
mk-url-preview
|
.avatar-anchor
|
||||||
margin-top 8px
|
display inline-block
|
||||||
|
|
||||||
> .reply
|
.avatar
|
||||||
margin-right 8px
|
vertical-align bottom
|
||||||
color #717171
|
width 28px
|
||||||
|
height 28px
|
||||||
|
margin 0 8px 0 0
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
> .quote
|
i
|
||||||
margin-left 4px
|
margin-right 4px
|
||||||
font-style oblique
|
|
||||||
color #a0bf46
|
|
||||||
|
|
||||||
> .media
|
.name
|
||||||
> img
|
font-weight bold
|
||||||
display block
|
|
||||||
max-width 100%
|
|
||||||
|
|
||||||
> .repost
|
> mk-time
|
||||||
margin 8px 0
|
position absolute
|
||||||
|
top 16px
|
||||||
|
right 32px
|
||||||
|
font-size 0.9em
|
||||||
|
line-height 28px
|
||||||
|
|
||||||
> i:first-child
|
& + article
|
||||||
position absolute
|
padding-top 8px
|
||||||
top -8px
|
|
||||||
left -8px
|
|
||||||
z-index 1
|
|
||||||
color #c0dac6
|
|
||||||
font-size 28px
|
|
||||||
background #fff
|
|
||||||
|
|
||||||
> mk-post-preview
|
> .reply-to
|
||||||
padding 16px
|
padding 0 16px
|
||||||
border dashed 1px #c0dac6
|
background rgba(0, 0, 0, 0.0125)
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
> footer
|
> mk-post-preview
|
||||||
> button
|
|
||||||
margin 0 28px 0 0
|
|
||||||
padding 0 8px
|
|
||||||
line-height 32px
|
|
||||||
font-size 1em
|
|
||||||
color #ddd
|
|
||||||
background transparent
|
background transparent
|
||||||
border none
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
&:hover
|
> article
|
||||||
color #666
|
padding 28px 32px 18px 32px
|
||||||
|
|
||||||
> .count
|
&:after
|
||||||
display inline
|
content ""
|
||||||
margin 0 0 0 8px
|
display block
|
||||||
color #999
|
clear both
|
||||||
|
|
||||||
&.liked
|
&:hover
|
||||||
color $theme-color
|
> .main > footer > button
|
||||||
|
color #888
|
||||||
|
|
||||||
&:last-child
|
> .avatar-anchor
|
||||||
position absolute
|
display block
|
||||||
right 0
|
float left
|
||||||
|
margin 0 16px 0 0
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
display block
|
||||||
|
width 58px
|
||||||
|
height 58px
|
||||||
margin 0
|
margin 0
|
||||||
|
border-radius 8px
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
> .detail
|
> .main
|
||||||
padding-top 4px
|
float left
|
||||||
background rgba(0, 0, 0, 0.0125)
|
width calc(100% - 74px)
|
||||||
|
|
||||||
style(theme='dark').
|
> header
|
||||||
background #0D0D0D
|
margin-bottom 4px
|
||||||
|
white-space nowrap
|
||||||
|
line-height 24px
|
||||||
|
|
||||||
> article
|
> .name
|
||||||
|
display inline
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
color #777
|
||||||
|
font-size 1em
|
||||||
|
font-weight 700
|
||||||
|
text-align left
|
||||||
|
text-decoration none
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
> .main > footer > button
|
text-decoration underline
|
||||||
color #eee
|
|
||||||
|
|
||||||
> .main
|
> .username
|
||||||
> header
|
text-align left
|
||||||
> .left
|
margin 0 0 0 8px
|
||||||
> .name
|
color #ccc
|
||||||
color #9e9c98
|
|
||||||
|
|
||||||
> .username
|
> .created-at
|
||||||
color #41403f
|
position absolute
|
||||||
|
top 0
|
||||||
|
right 0
|
||||||
|
font-size 0.9em
|
||||||
|
color #c0c0c0
|
||||||
|
|
||||||
> .right
|
> .body
|
||||||
> .time
|
|
||||||
color #4e4d4b
|
|
||||||
|
|
||||||
> .body
|
> .text
|
||||||
> .text
|
cursor default
|
||||||
color #9e9c98
|
display block
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
word-wrap break-word
|
||||||
|
font-size 1.1em
|
||||||
|
color #717171
|
||||||
|
|
||||||
> footer
|
mk-url-preview
|
||||||
> button
|
margin-top 8px
|
||||||
color #9e9c98
|
|
||||||
|
|
||||||
&:hover
|
> .reply
|
||||||
color #fff
|
margin-right 8px
|
||||||
|
color #717171
|
||||||
|
|
||||||
> .count
|
> .quote
|
||||||
color #eee
|
margin-left 4px
|
||||||
|
font-style oblique
|
||||||
|
color #a0bf46
|
||||||
|
|
||||||
script.
|
> .media
|
||||||
@mixin \api
|
> img
|
||||||
@mixin \text
|
display block
|
||||||
@mixin \date-stringify
|
max-width 100%
|
||||||
@mixin \user-preview
|
|
||||||
@mixin \NotImplementedException
|
|
||||||
|
|
||||||
@post = @opts.post
|
> .repost
|
||||||
@is-repost = @post.repost? and !@post.text?
|
margin 8px 0
|
||||||
@p = if @is-repost then @post.repost else @post
|
|
||||||
|
|
||||||
@title = @date-stringify @p.created_at
|
> i:first-child
|
||||||
|
position absolute
|
||||||
|
top -8px
|
||||||
|
left -8px
|
||||||
|
z-index 1
|
||||||
|
color #c0dac6
|
||||||
|
font-size 28px
|
||||||
|
background #fff
|
||||||
|
|
||||||
@url = CONFIG.url + '/' + @p.user.username + '/' + @p.id
|
> mk-post-preview
|
||||||
@is-detail-opened = false
|
padding 16px
|
||||||
|
border dashed 1px #c0dac6
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
@on \mount ~>
|
> footer
|
||||||
if @p.text?
|
> button
|
||||||
tokens = if @p._highlight?
|
margin 0 28px 0 0
|
||||||
then @analyze @p._highlight
|
padding 0 8px
|
||||||
else @analyze @p.text
|
line-height 32px
|
||||||
|
font-size 1em
|
||||||
|
color #ddd
|
||||||
|
background transparent
|
||||||
|
border none
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
@refs.text.innerHTML = if @p._highlight?
|
&:hover
|
||||||
then @compile tokens, true, false
|
color #666
|
||||||
else @compile tokens
|
|
||||||
|
|
||||||
@refs.text.children.for-each (e) ~>
|
> .count
|
||||||
if e.tag-name == \MK-URL
|
display inline
|
||||||
riot.mount e
|
margin 0 0 0 8px
|
||||||
|
color #999
|
||||||
|
|
||||||
# URLをプレビュー
|
&.liked
|
||||||
tokens
|
color $theme-color
|
||||||
.filter (t) -> t.type == \link
|
|
||||||
.map (t) ~>
|
|
||||||
@preview = @refs.text.append-child document.create-element \mk-url-preview
|
|
||||||
riot.mount @preview, do
|
|
||||||
url: t.content
|
|
||||||
|
|
||||||
@reply = ~>
|
&:last-child
|
||||||
form = document.body.append-child document.create-element \mk-post-form-window
|
position absolute
|
||||||
riot.mount form, do
|
right 0
|
||||||
reply: @p
|
margin 0
|
||||||
|
|
||||||
@repost = ~>
|
> .detail
|
||||||
form = document.body.append-child document.create-element \mk-repost-form-window
|
padding-top 4px
|
||||||
riot.mount form, do
|
background rgba(0, 0, 0, 0.0125)
|
||||||
post: @p
|
|
||||||
|
|
||||||
@like = ~>
|
</style>
|
||||||
if @p.is_liked
|
<script>
|
||||||
@api \posts/likes/delete do
|
@mixin \api
|
||||||
post_id: @p.id
|
@mixin \text
|
||||||
.then ~>
|
@mixin \date-stringify
|
||||||
@p.is_liked = false
|
@mixin \user-preview
|
||||||
@update!
|
@mixin \NotImplementedException
|
||||||
else
|
|
||||||
@api \posts/likes/create do
|
|
||||||
post_id: @p.id
|
|
||||||
.then ~>
|
|
||||||
@p.is_liked = true
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@toggle-detail = ~>
|
@post = @opts.post
|
||||||
@is-detail-opened = !@is-detail-opened
|
@is-repost = @post.repost? and !@post.text?
|
||||||
@update!
|
@p = if @is-repost then @post.repost else @post
|
||||||
|
|
||||||
@on-key-down = (e) ~>
|
@title = @date-stringify @p.created_at
|
||||||
should-be-cancel = true
|
|
||||||
switch
|
|
||||||
| e.which == 38 or e.which == 74 or (e.which == 9 and e.shift-key) => # ↑, j or Shift+Tab
|
|
||||||
focus @root, (e) -> e.previous-element-sibling
|
|
||||||
| e.which == 40 or e.which == 75 or e.which == 9 => # ↓, k or Tab
|
|
||||||
focus @root, (e) -> e.next-element-sibling
|
|
||||||
| e.which == 81 or e.which == 69 => # q or e
|
|
||||||
@repost!
|
|
||||||
| e.which == 70 or e.which == 76 => # f or l
|
|
||||||
@like!
|
|
||||||
| e.which == 82 => # r
|
|
||||||
@reply!
|
|
||||||
| _ =>
|
|
||||||
should-be-cancel = false
|
|
||||||
|
|
||||||
if should-be-cancel
|
@url = CONFIG.url + '/' + @p.user.username + '/' + @p.id
|
||||||
e.prevent-default!
|
@is-detail-opened = false
|
||||||
|
|
||||||
function focus(el, fn)
|
@on \mount ~>
|
||||||
target = fn el
|
if @p.text?
|
||||||
if target?
|
tokens = if @p._highlight?
|
||||||
if target.has-attribute \tabindex
|
then @analyze @p._highlight
|
||||||
target.focus!
|
else @analyze @p.text
|
||||||
|
|
||||||
|
@refs.text.innerHTML = if @p._highlight?
|
||||||
|
then @compile tokens, true, false
|
||||||
|
else @compile tokens
|
||||||
|
|
||||||
|
@refs.text.children.for-each (e) ~>
|
||||||
|
if e.tag-name == \MK-URL
|
||||||
|
riot.mount e
|
||||||
|
|
||||||
|
# URLをプレビュー
|
||||||
|
tokens
|
||||||
|
.filter (t) -> t.type == \link
|
||||||
|
.map (t) ~>
|
||||||
|
@preview = @refs.text.append-child document.create-element \mk-url-preview
|
||||||
|
riot.mount @preview, do
|
||||||
|
url: t.content
|
||||||
|
|
||||||
|
@reply = ~>
|
||||||
|
form = document.body.append-child document.create-element \mk-post-form-window
|
||||||
|
riot.mount form, do
|
||||||
|
reply: @p
|
||||||
|
|
||||||
|
@repost = ~>
|
||||||
|
form = document.body.append-child document.create-element \mk-repost-form-window
|
||||||
|
riot.mount form, do
|
||||||
|
post: @p
|
||||||
|
|
||||||
|
@like = ~>
|
||||||
|
if @p.is_liked
|
||||||
|
@api \posts/likes/delete do
|
||||||
|
post_id: @p.id
|
||||||
|
.then ~>
|
||||||
|
@p.is_liked = false
|
||||||
|
@update!
|
||||||
else
|
else
|
||||||
focus target, fn
|
@api \posts/likes/create do
|
||||||
|
post_id: @p.id
|
||||||
|
.then ~>
|
||||||
|
@p.is_liked = true
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@toggle-detail = ~>
|
||||||
|
@is-detail-opened = !@is-detail-opened
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@on-key-down = (e) ~>
|
||||||
|
should-be-cancel = true
|
||||||
|
switch
|
||||||
|
| e.which == 38 or e.which == 74 or (e.which == 9 and e.shift-key) => # ↑, j or Shift+Tab
|
||||||
|
focus @root, (e) -> e.previous-element-sibling
|
||||||
|
| e.which == 40 or e.which == 75 or e.which == 9 => # ↓, k or Tab
|
||||||
|
focus @root, (e) -> e.next-element-sibling
|
||||||
|
| e.which == 81 or e.which == 69 => # q or e
|
||||||
|
@repost!
|
||||||
|
| e.which == 70 or e.which == 76 => # f or l
|
||||||
|
@like!
|
||||||
|
| e.which == 82 => # r
|
||||||
|
@reply!
|
||||||
|
| _ =>
|
||||||
|
should-be-cancel = false
|
||||||
|
|
||||||
|
if should-be-cancel
|
||||||
|
e.prevent-default!
|
||||||
|
|
||||||
|
function focus(el, fn)
|
||||||
|
target = fn el
|
||||||
|
if target?
|
||||||
|
if target.has-attribute \tabindex
|
||||||
|
target.focus!
|
||||||
|
else
|
||||||
|
focus target, fn
|
||||||
|
</script>
|
||||||
|
</mk-timeline-post>
|
||||||
|
|
|
@ -1,86 +1,79 @@
|
||||||
mk-timeline
|
<mk-timeline>
|
||||||
virtual(each={ post, i in posts })
|
<virtual each="{ post, i in posts }">
|
||||||
mk-timeline-post(post={ post })
|
<mk-timeline-post post="{ post }"></mk-timeline-post>
|
||||||
p.date(if={ i != posts.length - 1 && post._date != posts[i + 1]._date })
|
<p class="date" if="{ i != posts.length - 1 && post._date != posts[i + 1]._date }"><span><i class="fa fa-angle-up"></i>{ post._datetext }</span><span><i class="fa fa-angle-down"></i>{ posts[i + 1]._datetext }</span></p>
|
||||||
span
|
</virtual>
|
||||||
i.fa.fa-angle-up
|
<footer data-yield="footer"><yield from="footer"/></footer>
|
||||||
| { post._datetext }
|
<style type="stylus">
|
||||||
span
|
:scope
|
||||||
i.fa.fa-angle-down
|
display block
|
||||||
| { posts[i + 1]._datetext }
|
|
||||||
footer(data-yield='footer')
|
|
||||||
| <yield from="footer"/>
|
|
||||||
|
|
||||||
style.
|
> mk-timeline-post
|
||||||
display block
|
border-bottom solid 1px #eaeaea
|
||||||
|
|
||||||
> mk-timeline-post
|
&:first-child
|
||||||
border-bottom solid 1px #eaeaea
|
border-top-left-radius 4px
|
||||||
|
border-top-right-radius 4px
|
||||||
|
|
||||||
&:first-child
|
&:last-of-type
|
||||||
border-top-left-radius 4px
|
border-bottom none
|
||||||
border-top-right-radius 4px
|
|
||||||
|
|
||||||
&:last-of-type
|
> .date
|
||||||
border-bottom none
|
display block
|
||||||
|
margin 0
|
||||||
|
line-height 32px
|
||||||
|
font-size 14px
|
||||||
|
text-align center
|
||||||
|
color #aaa
|
||||||
|
background #fdfdfd
|
||||||
|
border-bottom solid 1px #eaeaea
|
||||||
|
|
||||||
> .date
|
span
|
||||||
display block
|
margin 0 16px
|
||||||
margin 0
|
|
||||||
line-height 32px
|
|
||||||
font-size 14px
|
|
||||||
text-align center
|
|
||||||
color #aaa
|
|
||||||
background #fdfdfd
|
|
||||||
border-bottom solid 1px #eaeaea
|
|
||||||
|
|
||||||
span
|
i
|
||||||
margin 0 16px
|
margin-right 8px
|
||||||
|
|
||||||
i
|
> footer
|
||||||
margin-right 8px
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color #ccc
|
||||||
|
border-top solid 1px #eaeaea
|
||||||
|
border-bottom-left-radius 4px
|
||||||
|
border-bottom-right-radius 4px
|
||||||
|
|
||||||
> footer
|
</style>
|
||||||
padding 16px
|
<script>
|
||||||
text-align center
|
@posts = []
|
||||||
color #ccc
|
|
||||||
border-top solid 1px #eaeaea
|
|
||||||
border-bottom-left-radius 4px
|
|
||||||
border-bottom-right-radius 4px
|
|
||||||
|
|
||||||
style(theme='dark').
|
@set-posts = (posts) ~>
|
||||||
> mk-timeline-post
|
@posts = posts
|
||||||
border-bottom-color #222221
|
|
||||||
|
|
||||||
script.
|
|
||||||
@posts = []
|
|
||||||
|
|
||||||
@set-posts = (posts) ~>
|
|
||||||
@posts = posts
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@prepend-posts = (posts) ~>
|
|
||||||
posts.for-each (post) ~>
|
|
||||||
@posts.push post
|
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
@add-post = (post) ~>
|
@prepend-posts = (posts) ~>
|
||||||
@posts.unshift post
|
posts.for-each (post) ~>
|
||||||
@update!
|
@posts.push post
|
||||||
|
@update!
|
||||||
|
|
||||||
@clear = ~>
|
@add-post = (post) ~>
|
||||||
@posts = []
|
@posts.unshift post
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
@focus = ~>
|
@clear = ~>
|
||||||
@root.children.0.focus!
|
@posts = []
|
||||||
|
@update!
|
||||||
|
|
||||||
@on \update ~>
|
@focus = ~>
|
||||||
@posts.for-each (post) ~>
|
@root.children.0.focus!
|
||||||
date = (new Date post.created_at).get-date!
|
|
||||||
month = (new Date post.created_at).get-month! + 1
|
|
||||||
post._date = date
|
|
||||||
post._datetext = month + '月 ' + date + '日'
|
|
||||||
|
|
||||||
@tail = ~>
|
@on \update ~>
|
||||||
@posts[@posts.length - 1]
|
@posts.for-each (post) ~>
|
||||||
|
date = (new Date post.created_at).get-date!
|
||||||
|
month = (new Date post.created_at).get-month! + 1
|
||||||
|
post._date = date
|
||||||
|
post._datetext = month + '月 ' + date + '日'
|
||||||
|
|
||||||
|
@tail = ~>
|
||||||
|
@posts[@posts.length - 1]
|
||||||
|
</script>
|
||||||
|
</mk-timeline>
|
||||||
|
|
|
@ -1,219 +1,212 @@
|
||||||
mk-ui-header-account
|
<mk-ui-header-account>
|
||||||
button.header(data-active={ is-open.toString() }, onclick={ toggle })
|
<button class="header" data-active="{ isOpen.toString() }" onclick="{ toggle }"><span class="username">{ I.username }<i class="fa fa-angle-down" if="{ !isOpen }"></i><i class="fa fa-angle-up" if="{ isOpen }"></i></span><img class="avatar" src="{ I.avatar_url + '?thumbnail&size=64' }" alt="avatar"/></button>
|
||||||
span.username
|
<div class="menu" if="{ isOpen }">
|
||||||
| { I.username }
|
<ul>
|
||||||
i.fa.fa-angle-down(if={ !is-open })
|
<li><a href="{ '/' + I.username }"><i class="fa fa-user"></i>プロフィール<i class="fa fa-angle-right"></i></a></li>
|
||||||
i.fa.fa-angle-up(if={ is-open })
|
<li onclick="{ drive }">
|
||||||
img.avatar(src={ I.avatar_url + '?thumbnail&size=64' }, alt='avatar')
|
<p><i class="fa fa-cloud"></i>ドライブ<i class="fa fa-angle-right"></i></p>
|
||||||
div.menu(if={ is-open })
|
</li>
|
||||||
ul
|
<li><a href="/i>mentions"><i class="fa fa-at"></i>あなた宛て<i class="fa fa-angle-right"></i></a></li>
|
||||||
li: a(href={ '/' + I.username })
|
</ul>
|
||||||
i.fa.fa-user
|
<ul>
|
||||||
| プロフィール
|
<li onclick="{ settings }">
|
||||||
i.fa.fa-angle-right
|
<p><i class="fa fa-cog"></i>設定<i class="fa fa-angle-right"></i></p>
|
||||||
li(onclick={ drive }): p
|
</li>
|
||||||
i.fa.fa-cloud
|
</ul>
|
||||||
| ドライブ
|
<ul>
|
||||||
i.fa.fa-angle-right
|
<li onclick="{ signout }">
|
||||||
li: a(href='/i>mentions')
|
<p><i class="fa fa-power-off"></i>サインアウト<i class="fa fa-angle-right"></i></p>
|
||||||
i.fa.fa-at
|
</li>
|
||||||
| あなた宛て
|
</ul>
|
||||||
i.fa.fa-angle-right
|
</div>
|
||||||
ul
|
<style type="stylus">
|
||||||
li(onclick={ settings }): p
|
:scope
|
||||||
i.fa.fa-cog
|
|
||||||
| 設定
|
|
||||||
i.fa.fa-angle-right
|
|
||||||
ul
|
|
||||||
li(onclick={ signout }): p
|
|
||||||
i(class='fa fa-power-off')
|
|
||||||
| サインアウト
|
|
||||||
i.fa.fa-angle-right
|
|
||||||
|
|
||||||
style.
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
|
|
||||||
> .header
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
color #9eaba8
|
|
||||||
border none
|
|
||||||
background transparent
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
*
|
|
||||||
pointer-events none
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color darken(#9eaba8, 20%)
|
|
||||||
|
|
||||||
&:active
|
|
||||||
color darken(#9eaba8, 30%)
|
|
||||||
|
|
||||||
&[data-active='true']
|
|
||||||
color darken(#9eaba8, 20%)
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
$saturate = 150%
|
|
||||||
filter saturate($saturate)
|
|
||||||
-webkit-filter saturate($saturate)
|
|
||||||
-moz-filter saturate($saturate)
|
|
||||||
-ms-filter saturate($saturate)
|
|
||||||
|
|
||||||
> .username
|
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
margin 0 12px 0 16px
|
|
||||||
max-width 16em
|
|
||||||
line-height 48px
|
|
||||||
font-weight bold
|
|
||||||
font-family Meiryo, sans-serif
|
|
||||||
text-decoration none
|
|
||||||
|
|
||||||
i
|
> .header
|
||||||
margin-left 8px
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
min-width 32px
|
|
||||||
max-width 32px
|
|
||||||
min-height 32px
|
|
||||||
max-height 32px
|
|
||||||
margin 8px 8px 8px 0
|
|
||||||
border-radius 4px
|
|
||||||
transition filter 100ms ease
|
|
||||||
|
|
||||||
> .menu
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 56px
|
|
||||||
right -2px
|
|
||||||
width 230px
|
|
||||||
font-size 0.8em
|
|
||||||
background #fff
|
|
||||||
border-radius 4px
|
|
||||||
box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
|
|
||||||
|
|
||||||
&:before
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top -28px
|
|
||||||
right 12px
|
|
||||||
border-top solid 14px transparent
|
|
||||||
border-right solid 14px transparent
|
|
||||||
border-bottom solid 14px rgba(0, 0, 0, 0.1)
|
|
||||||
border-left solid 14px transparent
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top -27px
|
|
||||||
right 12px
|
|
||||||
border-top solid 14px transparent
|
|
||||||
border-right solid 14px transparent
|
|
||||||
border-bottom solid 14px #fff
|
|
||||||
border-left solid 14px transparent
|
|
||||||
|
|
||||||
ul
|
|
||||||
display block
|
|
||||||
margin 10px 0
|
|
||||||
padding 0
|
|
||||||
list-style none
|
|
||||||
|
|
||||||
& + ul
|
|
||||||
padding-top 10px
|
|
||||||
border-top solid 1px #eee
|
|
||||||
|
|
||||||
> li
|
|
||||||
display block
|
display block
|
||||||
margin 0
|
margin 0
|
||||||
padding 0
|
padding 0
|
||||||
|
color #9eaba8
|
||||||
|
border none
|
||||||
|
background transparent
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
> a
|
*
|
||||||
> p
|
pointer-events none
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
color darken(#9eaba8, 20%)
|
||||||
|
|
||||||
|
&:active
|
||||||
|
color darken(#9eaba8, 30%)
|
||||||
|
|
||||||
|
&[data-active='true']
|
||||||
|
color darken(#9eaba8, 20%)
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
$saturate = 150%
|
||||||
|
filter saturate($saturate)
|
||||||
|
-webkit-filter saturate($saturate)
|
||||||
|
-moz-filter saturate($saturate)
|
||||||
|
-ms-filter saturate($saturate)
|
||||||
|
|
||||||
|
> .username
|
||||||
display block
|
display block
|
||||||
z-index 1
|
float left
|
||||||
padding 0 28px
|
margin 0 12px 0 16px
|
||||||
margin 0
|
max-width 16em
|
||||||
line-height 40px
|
line-height 48px
|
||||||
color #868C8C
|
font-weight bold
|
||||||
cursor pointer
|
font-family Meiryo, sans-serif
|
||||||
|
text-decoration none
|
||||||
|
|
||||||
*
|
i
|
||||||
pointer-events none
|
margin-left 8px
|
||||||
|
|
||||||
> i:first-of-type
|
> .avatar
|
||||||
margin-right 6px
|
display block
|
||||||
|
float left
|
||||||
|
min-width 32px
|
||||||
|
max-width 32px
|
||||||
|
min-height 32px
|
||||||
|
max-height 32px
|
||||||
|
margin 8px 8px 8px 0
|
||||||
|
border-radius 4px
|
||||||
|
transition filter 100ms ease
|
||||||
|
|
||||||
> i:last-of-type
|
> .menu
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top 56px
|
||||||
|
right -2px
|
||||||
|
width 230px
|
||||||
|
font-size 0.8em
|
||||||
|
background #fff
|
||||||
|
border-radius 4px
|
||||||
|
box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
|
||||||
|
|
||||||
|
&:before
|
||||||
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top -28px
|
||||||
|
right 12px
|
||||||
|
border-top solid 14px transparent
|
||||||
|
border-right solid 14px transparent
|
||||||
|
border-bottom solid 14px rgba(0, 0, 0, 0.1)
|
||||||
|
border-left solid 14px transparent
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top -27px
|
||||||
|
right 12px
|
||||||
|
border-top solid 14px transparent
|
||||||
|
border-right solid 14px transparent
|
||||||
|
border-bottom solid 14px #fff
|
||||||
|
border-left solid 14px transparent
|
||||||
|
|
||||||
|
ul
|
||||||
|
display block
|
||||||
|
margin 10px 0
|
||||||
|
padding 0
|
||||||
|
list-style none
|
||||||
|
|
||||||
|
& + ul
|
||||||
|
padding-top 10px
|
||||||
|
border-top solid 1px #eee
|
||||||
|
|
||||||
|
> li
|
||||||
display block
|
display block
|
||||||
position absolute
|
margin 0
|
||||||
top 0
|
padding 0
|
||||||
right 8px
|
|
||||||
z-index 1
|
|
||||||
padding 0 20px
|
|
||||||
font-size 1.2em
|
|
||||||
line-height 40px
|
|
||||||
|
|
||||||
&:hover, &:active
|
> a
|
||||||
text-decoration none
|
> p
|
||||||
background $theme-color
|
display block
|
||||||
color $theme-color-foreground
|
z-index 1
|
||||||
|
padding 0 28px
|
||||||
|
margin 0
|
||||||
|
line-height 40px
|
||||||
|
color #868C8C
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
script.
|
*
|
||||||
@mixin \i
|
pointer-events none
|
||||||
@mixin \signout
|
|
||||||
|
|
||||||
@is-open = false
|
> i:first-of-type
|
||||||
|
margin-right 6px
|
||||||
|
|
||||||
@on \before-unmount ~>
|
> i:last-of-type
|
||||||
@close!
|
display block
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
right 8px
|
||||||
|
z-index 1
|
||||||
|
padding 0 20px
|
||||||
|
font-size 1.2em
|
||||||
|
line-height 40px
|
||||||
|
|
||||||
@toggle = ~>
|
&:hover, &:active
|
||||||
if @is-open
|
text-decoration none
|
||||||
@close!
|
background $theme-color
|
||||||
else
|
color $theme-color-foreground
|
||||||
@open!
|
|
||||||
|
|
||||||
@open = ~>
|
</style>
|
||||||
@is-open = true
|
<script>
|
||||||
@update!
|
@mixin \i
|
||||||
all = document.query-selector-all 'body *'
|
@mixin \signout
|
||||||
Array.prototype.for-each.call all, (el) ~>
|
|
||||||
el.add-event-listener \mousedown @mousedown
|
|
||||||
|
|
||||||
@close = ~>
|
|
||||||
@is-open = false
|
@is-open = false
|
||||||
@update!
|
|
||||||
all = document.query-selector-all 'body *'
|
|
||||||
Array.prototype.for-each.call all, (el) ~>
|
|
||||||
el.remove-event-listener \mousedown @mousedown
|
|
||||||
|
|
||||||
@mousedown = (e) ~>
|
@on \before-unmount ~>
|
||||||
e.prevent-default!
|
|
||||||
if (!contains @root, e.target) and (@root != e.target)
|
|
||||||
@close!
|
@close!
|
||||||
return false
|
|
||||||
|
|
||||||
@drive = ~>
|
@toggle = ~>
|
||||||
@close!
|
if @is-open
|
||||||
riot.mount document.body.append-child document.create-element \mk-drive-browser-window
|
@close!
|
||||||
|
else
|
||||||
|
@open!
|
||||||
|
|
||||||
@settings = ~>
|
@open = ~>
|
||||||
@close!
|
@is-open = true
|
||||||
riot.mount document.body.append-child document.create-element \mk-settings-window
|
@update!
|
||||||
|
all = document.query-selector-all 'body *'
|
||||||
|
Array.prototype.for-each.call all, (el) ~>
|
||||||
|
el.add-event-listener \mousedown @mousedown
|
||||||
|
|
||||||
function contains(parent, child)
|
@close = ~>
|
||||||
node = child.parent-node
|
@is-open = false
|
||||||
while node?
|
@update!
|
||||||
if node == parent
|
all = document.query-selector-all 'body *'
|
||||||
return true
|
Array.prototype.for-each.call all, (el) ~>
|
||||||
node = node.parent-node
|
el.remove-event-listener \mousedown @mousedown
|
||||||
return false
|
|
||||||
|
@mousedown = (e) ~>
|
||||||
|
e.prevent-default!
|
||||||
|
if (!contains @root, e.target) and (@root != e.target)
|
||||||
|
@close!
|
||||||
|
return false
|
||||||
|
|
||||||
|
@drive = ~>
|
||||||
|
@close!
|
||||||
|
riot.mount document.body.append-child document.create-element \mk-drive-browser-window
|
||||||
|
|
||||||
|
@settings = ~>
|
||||||
|
@close!
|
||||||
|
riot.mount document.body.append-child document.create-element \mk-settings-window
|
||||||
|
|
||||||
|
function contains(parent, child)
|
||||||
|
node = child.parent-node
|
||||||
|
while node?
|
||||||
|
if node == parent
|
||||||
|
return true
|
||||||
|
node = node.parent-node
|
||||||
|
return false
|
||||||
|
</script>
|
||||||
|
</mk-ui-header-account>
|
||||||
|
|
|
@ -1,82 +1,87 @@
|
||||||
mk-ui-header-clock
|
<mk-ui-header-clock>
|
||||||
div.header
|
<div class="header">
|
||||||
time@time
|
<time ref="time"></time>
|
||||||
div.content
|
</div>
|
||||||
mk-analog-clock
|
<div class="content">
|
||||||
|
<mk-analog-clock></mk-analog-clock>
|
||||||
|
</div>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display inline-block
|
||||||
|
overflow visible
|
||||||
|
|
||||||
style.
|
> .header
|
||||||
display inline-block
|
padding 0 12px
|
||||||
overflow visible
|
text-align center
|
||||||
|
font-size 0.5em
|
||||||
|
|
||||||
> .header
|
&, *
|
||||||
padding 0 12px
|
cursor: default
|
||||||
text-align center
|
|
||||||
font-size 0.5em
|
|
||||||
|
|
||||||
&, *
|
&:hover
|
||||||
cursor: default
|
background #899492
|
||||||
|
|
||||||
&:hover
|
& + .content
|
||||||
background #899492
|
visibility visible
|
||||||
|
|
||||||
& + .content
|
> time
|
||||||
visibility visible
|
color #fff !important
|
||||||
|
|
||||||
> time
|
*
|
||||||
color #fff !important
|
color #fff !important
|
||||||
|
|
||||||
*
|
&:after
|
||||||
color #fff !important
|
content ""
|
||||||
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
&:after
|
> time
|
||||||
content ""
|
display table-cell
|
||||||
display block
|
vertical-align middle
|
||||||
clear both
|
height 48px
|
||||||
|
color #9eaba8
|
||||||
|
|
||||||
> time
|
> .yyyymmdd
|
||||||
display table-cell
|
opacity 0.7
|
||||||
vertical-align middle
|
|
||||||
height 48px
|
|
||||||
color #9eaba8
|
|
||||||
|
|
||||||
> .yyyymmdd
|
> .content
|
||||||
opacity 0.7
|
visibility hidden
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top auto
|
||||||
|
right 0
|
||||||
|
z-index 3
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
width 256px
|
||||||
|
background #899492
|
||||||
|
|
||||||
> .content
|
</style>
|
||||||
visibility hidden
|
<script>
|
||||||
display block
|
@draw = ~>
|
||||||
position absolute
|
now = new Date!
|
||||||
top auto
|
|
||||||
right 0
|
|
||||||
z-index 3
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
width 256px
|
|
||||||
background #899492
|
|
||||||
|
|
||||||
script.
|
yyyy = now.get-full-year!
|
||||||
@draw = ~>
|
mm = (\0 + (now.get-month! + 1)).slice -2
|
||||||
now = new Date!
|
dd = (\0 + now.get-date!).slice -2
|
||||||
|
yyyymmdd = "<span class='yyyymmdd'>#yyyy/#mm/#dd</span>"
|
||||||
|
|
||||||
yyyy = now.get-full-year!
|
hh = (\0 + now.get-hours!).slice -2
|
||||||
mm = (\0 + (now.get-month! + 1)).slice -2
|
mm = (\0 + now.get-minutes!).slice -2
|
||||||
dd = (\0 + now.get-date!).slice -2
|
hhmm = "<span class='hhmm'>#hh:#mm</span>"
|
||||||
yyyymmdd = "<span class='yyyymmdd'>#yyyy/#mm/#dd</span>"
|
|
||||||
|
|
||||||
hh = (\0 + now.get-hours!).slice -2
|
if now.get-seconds! % 2 == 0
|
||||||
mm = (\0 + now.get-minutes!).slice -2
|
hhmm .= replace \: '<span style=\'visibility:visible\'>:</span>'
|
||||||
hhmm = "<span class='hhmm'>#hh:#mm</span>"
|
else
|
||||||
|
hhmm .= replace \: '<span style=\'visibility:hidden\'>:</span>'
|
||||||
|
|
||||||
if now.get-seconds! % 2 == 0
|
@refs.time.innerHTML = "#yyyymmdd<br>#hhmm"
|
||||||
hhmm .= replace \: '<span style=\'visibility:visible\'>:</span>'
|
|
||||||
else
|
|
||||||
hhmm .= replace \: '<span style=\'visibility:hidden\'>:</span>'
|
|
||||||
|
|
||||||
@refs.time.innerHTML = "#yyyymmdd<br>#hhmm"
|
@on \mount ~>
|
||||||
|
@draw!
|
||||||
|
@clock = set-interval @draw, 1000ms
|
||||||
|
|
||||||
@on \mount ~>
|
@on \unmount ~>
|
||||||
@draw!
|
clear-interval @clock
|
||||||
@clock = set-interval @draw, 1000ms
|
</script>
|
||||||
|
</mk-ui-header-clock>
|
||||||
@on \unmount ~>
|
|
||||||
clear-interval @clock
|
|
||||||
|
|
|
@ -1,113 +1,113 @@
|
||||||
mk-ui-header-nav: ul(if={ SIGNIN })
|
<mk-ui-header-nav>
|
||||||
li.home(class={ active: page == 'home' }): a(href={ CONFIG.url })
|
<ul if="{ SIGNIN }">
|
||||||
i.fa.fa-home
|
<li class="home { active: page == 'home' }"><a href="{ CONFIG.url }"><i class="fa fa-home"></i>
|
||||||
p ホーム
|
<p>ホーム</p></a></li>
|
||||||
li.messaging: a(onclick={ messaging })
|
<li class="messaging"><a onclick="{ messaging }"><i class="fa fa-comments"></i>
|
||||||
i.fa.fa-comments
|
<p>メッセージ</p><i class="fa fa-circle" if="{ hasUnreadMessagingMessages }"></i></a></li>
|
||||||
p メッセージ
|
<li class="info"><a href="https://twitter.com/misskey_xyz" target="_blank"><i class="fa fa-info"></i>
|
||||||
i.fa.fa-circle(if={ has-unread-messaging-messages })
|
<p>お知らせ</p></a></li>
|
||||||
li.info: a(href='https://twitter.com/misskey_xyz', target='_blank')
|
<li class="tv"><a href="https://misskey.tk" target="_blank"><i class="fa fa-television"></i>
|
||||||
i.fa.fa-info
|
<p>MisskeyTV™</p></a></li>
|
||||||
p お知らせ
|
<style type="stylus">
|
||||||
li.tv: a(href='https://misskey.tk', target='_blank')
|
:scope
|
||||||
i.fa.fa-television
|
|
||||||
p MisskeyTV™
|
|
||||||
|
|
||||||
style.
|
|
||||||
display inline-block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
line-height 3rem
|
|
||||||
vertical-align top
|
|
||||||
|
|
||||||
> ul
|
|
||||||
display inline-block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
vertical-align top
|
|
||||||
line-height 3rem
|
|
||||||
list-style none
|
|
||||||
|
|
||||||
> li
|
|
||||||
display inline-block
|
|
||||||
vertical-align top
|
|
||||||
height 48px
|
|
||||||
line-height 48px
|
|
||||||
|
|
||||||
&.active
|
|
||||||
> a
|
|
||||||
border-bottom solid 3px $theme-color
|
|
||||||
|
|
||||||
> a
|
|
||||||
display inline-block
|
display inline-block
|
||||||
z-index 1
|
margin 0
|
||||||
height 100%
|
padding 0
|
||||||
padding 0 24px
|
line-height 3rem
|
||||||
font-size 1em
|
vertical-align top
|
||||||
font-variant small-caps
|
|
||||||
color #9eaba8
|
|
||||||
text-decoration none
|
|
||||||
transition none
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
*
|
> ul
|
||||||
pointer-events none
|
display inline-block
|
||||||
|
|
||||||
&:hover
|
|
||||||
color darken(#9eaba8, 20%)
|
|
||||||
text-decoration none
|
|
||||||
|
|
||||||
> i:first-child
|
|
||||||
margin-right 8px
|
|
||||||
|
|
||||||
> i:last-child
|
|
||||||
margin-left 5px
|
|
||||||
vertical-align super
|
|
||||||
font-size 10px
|
|
||||||
color $theme-color
|
|
||||||
|
|
||||||
@media (max-width 1100px)
|
|
||||||
margin-left -5px
|
|
||||||
|
|
||||||
> p
|
|
||||||
display inline
|
|
||||||
margin 0
|
margin 0
|
||||||
|
padding 0
|
||||||
|
vertical-align top
|
||||||
|
line-height 3rem
|
||||||
|
list-style none
|
||||||
|
|
||||||
@media (max-width 1100px)
|
> li
|
||||||
display none
|
display inline-block
|
||||||
|
vertical-align top
|
||||||
|
height 48px
|
||||||
|
line-height 48px
|
||||||
|
|
||||||
@media (max-width 700px)
|
&.active
|
||||||
padding 0 12px
|
> a
|
||||||
|
border-bottom solid 3px $theme-color
|
||||||
|
|
||||||
script.
|
> a
|
||||||
@mixin \i
|
display inline-block
|
||||||
@mixin \api
|
z-index 1
|
||||||
@mixin \stream
|
height 100%
|
||||||
|
padding 0 24px
|
||||||
|
font-size 1em
|
||||||
|
font-variant small-caps
|
||||||
|
color #9eaba8
|
||||||
|
text-decoration none
|
||||||
|
transition none
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
@page = @opts.page
|
*
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
@on \mount ~>
|
&:hover
|
||||||
@stream.on \read_all_messaging_messages @on-read-all-messaging-messages
|
color darken(#9eaba8, 20%)
|
||||||
@stream.on \unread_messaging_message @on-unread-messaging-message
|
text-decoration none
|
||||||
|
|
||||||
# Fetch count of unread messaging messages
|
> i:first-child
|
||||||
@api \messaging/unread
|
margin-right 8px
|
||||||
.then (count) ~>
|
|
||||||
if count.count > 0
|
> i:last-child
|
||||||
|
margin-left 5px
|
||||||
|
vertical-align super
|
||||||
|
font-size 10px
|
||||||
|
color $theme-color
|
||||||
|
|
||||||
|
@media (max-width 1100px)
|
||||||
|
margin-left -5px
|
||||||
|
|
||||||
|
> p
|
||||||
|
display inline
|
||||||
|
margin 0
|
||||||
|
|
||||||
|
@media (max-width 1100px)
|
||||||
|
display none
|
||||||
|
|
||||||
|
@media (max-width 700px)
|
||||||
|
padding 0 12px
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
@mixin \i
|
||||||
|
@mixin \api
|
||||||
|
@mixin \stream
|
||||||
|
|
||||||
|
@page = @opts.page
|
||||||
|
|
||||||
|
@on \mount ~>
|
||||||
|
@stream.on \read_all_messaging_messages @on-read-all-messaging-messages
|
||||||
|
@stream.on \unread_messaging_message @on-unread-messaging-message
|
||||||
|
|
||||||
|
# Fetch count of unread messaging messages
|
||||||
|
@api \messaging/unread
|
||||||
|
.then (count) ~>
|
||||||
|
if count.count > 0
|
||||||
|
@has-unread-messaging-messages = true
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@on \unmount ~>
|
||||||
|
@stream.off \read_all_messaging_messages @on-read-all-messaging-messages
|
||||||
|
@stream.off \unread_messaging_message @on-unread-messaging-message
|
||||||
|
|
||||||
|
@on-read-all-messaging-messages = ~>
|
||||||
|
@has-unread-messaging-messages = false
|
||||||
|
@update!
|
||||||
|
|
||||||
|
@on-unread-messaging-message = ~>
|
||||||
@has-unread-messaging-messages = true
|
@has-unread-messaging-messages = true
|
||||||
@update!
|
@update!
|
||||||
|
|
||||||
@on \unmount ~>
|
@messaging = ~>
|
||||||
@stream.off \read_all_messaging_messages @on-read-all-messaging-messages
|
riot.mount document.body.append-child document.create-element \mk-messaging-window
|
||||||
@stream.off \unread_messaging_message @on-unread-messaging-message
|
</script>
|
||||||
|
</ul>
|
||||||
@on-read-all-messaging-messages = ~>
|
</mk-ui-header-nav>
|
||||||
@has-unread-messaging-messages = false
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@on-unread-messaging-message = ~>
|
|
||||||
@has-unread-messaging-messages = true
|
|
||||||
@update!
|
|
||||||
|
|
||||||
@messaging = ~>
|
|
||||||
riot.mount document.body.append-child document.create-element \mk-messaging-window
|
|
||||||
|
|
|
@ -1,111 +1,114 @@
|
||||||
mk-ui-header-notifications
|
<mk-ui-header-notifications>
|
||||||
button.header(data-active={ is-open }, onclick={ toggle })
|
<button class="header" data-active="{ isOpen }" onclick="{ toggle }"><i class="fa fa-bell-o"></i></button>
|
||||||
i.fa.fa-bell-o
|
<div class="notifications" if="{ isOpen }">
|
||||||
div.notifications(if={ is-open })
|
<mk-notifications></mk-notifications>
|
||||||
mk-notifications
|
</div>
|
||||||
|
<style type="stylus">
|
||||||
style.
|
:scope
|
||||||
display block
|
|
||||||
float left
|
|
||||||
|
|
||||||
> .header
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
width 32px
|
|
||||||
color #9eaba8
|
|
||||||
border none
|
|
||||||
background transparent
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
*
|
|
||||||
pointer-events none
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color darken(#9eaba8, 20%)
|
|
||||||
|
|
||||||
&:active
|
|
||||||
color darken(#9eaba8, 30%)
|
|
||||||
|
|
||||||
&[data-active='true']
|
|
||||||
color darken(#9eaba8, 20%)
|
|
||||||
|
|
||||||
> i
|
|
||||||
font-size 1.2em
|
|
||||||
line-height 48px
|
|
||||||
|
|
||||||
> .notifications
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 56px
|
|
||||||
right -72px
|
|
||||||
width 300px
|
|
||||||
background #fff
|
|
||||||
border-radius 4px
|
|
||||||
box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
|
|
||||||
|
|
||||||
&:before
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
display block
|
display block
|
||||||
position absolute
|
float left
|
||||||
top -28px
|
|
||||||
right 74px
|
|
||||||
border-top solid 14px transparent
|
|
||||||
border-right solid 14px transparent
|
|
||||||
border-bottom solid 14px rgba(0, 0, 0, 0.1)
|
|
||||||
border-left solid 14px transparent
|
|
||||||
|
|
||||||
&:after
|
> .header
|
||||||
content ""
|
display block
|
||||||
pointer-events none
|
margin 0
|
||||||
display block
|
padding 0
|
||||||
position absolute
|
width 32px
|
||||||
top -27px
|
color #9eaba8
|
||||||
right 74px
|
border none
|
||||||
border-top solid 14px transparent
|
background transparent
|
||||||
border-right solid 14px transparent
|
cursor pointer
|
||||||
border-bottom solid 14px #fff
|
|
||||||
border-left solid 14px transparent
|
|
||||||
|
|
||||||
> mk-notifications
|
*
|
||||||
max-height 350px
|
pointer-events none
|
||||||
font-size 1rem
|
|
||||||
overflow auto
|
|
||||||
|
|
||||||
script.
|
&:hover
|
||||||
@is-open = false
|
color darken(#9eaba8, 20%)
|
||||||
|
|
||||||
@toggle = ~>
|
&:active
|
||||||
if @is-open
|
color darken(#9eaba8, 30%)
|
||||||
@close!
|
|
||||||
else
|
|
||||||
@open!
|
|
||||||
|
|
||||||
@open = ~>
|
&[data-active='true']
|
||||||
@is-open = true
|
color darken(#9eaba8, 20%)
|
||||||
@update!
|
|
||||||
all = document.query-selector-all 'body *'
|
|
||||||
Array.prototype.for-each.call all, (el) ~>
|
|
||||||
el.add-event-listener \mousedown @mousedown
|
|
||||||
|
|
||||||
@close = ~>
|
> i
|
||||||
|
font-size 1.2em
|
||||||
|
line-height 48px
|
||||||
|
|
||||||
|
> .notifications
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top 56px
|
||||||
|
right -72px
|
||||||
|
width 300px
|
||||||
|
background #fff
|
||||||
|
border-radius 4px
|
||||||
|
box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
|
||||||
|
|
||||||
|
&:before
|
||||||
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top -28px
|
||||||
|
right 74px
|
||||||
|
border-top solid 14px transparent
|
||||||
|
border-right solid 14px transparent
|
||||||
|
border-bottom solid 14px rgba(0, 0, 0, 0.1)
|
||||||
|
border-left solid 14px transparent
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ""
|
||||||
|
pointer-events none
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top -27px
|
||||||
|
right 74px
|
||||||
|
border-top solid 14px transparent
|
||||||
|
border-right solid 14px transparent
|
||||||
|
border-bottom solid 14px #fff
|
||||||
|
border-left solid 14px transparent
|
||||||
|
|
||||||
|
> mk-notifications
|
||||||
|
max-height 350px
|
||||||
|
font-size 1rem
|
||||||
|
overflow auto
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
@is-open = false
|
@is-open = false
|
||||||
@update!
|
|
||||||
all = document.query-selector-all 'body *'
|
|
||||||
Array.prototype.for-each.call all, (el) ~>
|
|
||||||
el.remove-event-listener \mousedown @mousedown
|
|
||||||
|
|
||||||
@mousedown = (e) ~>
|
@toggle = ~>
|
||||||
e.prevent-default!
|
if @is-open
|
||||||
if (!contains @root, e.target) and (@root != e.target)
|
@close!
|
||||||
@close!
|
else
|
||||||
return false
|
@open!
|
||||||
|
|
||||||
function contains(parent, child)
|
@open = ~>
|
||||||
node = child.parent-node
|
@is-open = true
|
||||||
while node?
|
@update!
|
||||||
if node == parent
|
all = document.query-selector-all 'body *'
|
||||||
return true
|
Array.prototype.for-each.call all, (el) ~>
|
||||||
node = node.parent-node
|
el.add-event-listener \mousedown @mousedown
|
||||||
return false
|
|
||||||
|
@close = ~>
|
||||||
|
@is-open = false
|
||||||
|
@update!
|
||||||
|
all = document.query-selector-all 'body *'
|
||||||
|
Array.prototype.for-each.call all, (el) ~>
|
||||||
|
el.remove-event-listener \mousedown @mousedown
|
||||||
|
|
||||||
|
@mousedown = (e) ~>
|
||||||
|
e.prevent-default!
|
||||||
|
if (!contains @root, e.target) and (@root != e.target)
|
||||||
|
@close!
|
||||||
|
return false
|
||||||
|
|
||||||
|
function contains(parent, child)
|
||||||
|
node = child.parent-node
|
||||||
|
while node?
|
||||||
|
if node == parent
|
||||||
|
return true
|
||||||
|
node = node.parent-node
|
||||||
|
return false
|
||||||
|
</script>
|
||||||
|
</mk-ui-header-notifications>
|
||||||
|
|
|
@ -1,39 +1,41 @@
|
||||||
mk-ui-header-post-button
|
<mk-ui-header-post-button>
|
||||||
button(onclick={ post }, title='新規投稿')
|
<button onclick="{ post }" title="新規投稿"><i class="fa fa-pencil-square-o"></i></button>
|
||||||
i.fa.fa-pencil-square-o
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
display inline-block
|
||||||
|
padding 8px
|
||||||
|
height 100%
|
||||||
|
vertical-align top
|
||||||
|
|
||||||
style.
|
> button
|
||||||
display inline-block
|
display inline-block
|
||||||
padding 8px
|
margin 0
|
||||||
height 100%
|
padding 0 10px
|
||||||
vertical-align top
|
height 100%
|
||||||
|
font-size 1.2em
|
||||||
|
font-weight normal
|
||||||
|
text-decoration none
|
||||||
|
color $theme-color-foreground
|
||||||
|
background $theme-color !important
|
||||||
|
outline none
|
||||||
|
border none
|
||||||
|
border-radius 2px
|
||||||
|
transition background 0.1s ease
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
> button
|
*
|
||||||
display inline-block
|
pointer-events none
|
||||||
margin 0
|
|
||||||
padding 0 10px
|
|
||||||
height 100%
|
|
||||||
font-size 1.2em
|
|
||||||
font-weight normal
|
|
||||||
text-decoration none
|
|
||||||
color $theme-color-foreground
|
|
||||||
background $theme-color !important
|
|
||||||
outline none
|
|
||||||
border none
|
|
||||||
border-radius 2px
|
|
||||||
transition background 0.1s ease
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
*
|
&:hover
|
||||||
pointer-events none
|
background lighten($theme-color, 10%) !important
|
||||||
|
|
||||||
&:hover
|
&:active
|
||||||
background lighten($theme-color, 10%) !important
|
background darken($theme-color, 10%) !important
|
||||||
|
transition background 0s ease
|
||||||
|
|
||||||
&:active
|
</style>
|
||||||
background darken($theme-color, 10%) !important
|
<script>
|
||||||
transition background 0s ease
|
@post = (e) ~>
|
||||||
|
@parent.parent.open-post-form!
|
||||||
script.
|
</script>
|
||||||
@post = (e) ~>
|
</mk-ui-header-post-button>
|
||||||
@parent.parent.open-post-form!
|
|
||||||
|
|
|
@ -1,37 +1,41 @@
|
||||||
mk-ui-header-search
|
<mk-ui-header-search>
|
||||||
form.search(onsubmit={ onsubmit })
|
<form class="search" onsubmit="{ onsubmit }">
|
||||||
input@q(type='search', placeholder!=' 検索')
|
<input ref="q" type="search" placeholder=" 検索"/>
|
||||||
div.result
|
<div class="result"></div>
|
||||||
|
</form>
|
||||||
|
<style type="stylus">
|
||||||
|
:scope
|
||||||
|
|
||||||
style.
|
> form
|
||||||
|
display block
|
||||||
|
float left
|
||||||
|
|
||||||
> form
|
> input
|
||||||
display block
|
user-select text
|
||||||
float left
|
cursor auto
|
||||||
|
margin 0
|
||||||
|
padding 6px 18px
|
||||||
|
width 14em
|
||||||
|
height 48px
|
||||||
|
font-size 1em
|
||||||
|
line-height calc(48px - 12px)
|
||||||
|
background transparent
|
||||||
|
outline none
|
||||||
|
//border solid 1px #ddd
|
||||||
|
border none
|
||||||
|
border-radius 0
|
||||||
|
transition color 0.5s ease, border 0.5s ease
|
||||||
|
font-family FontAwesome, sans-serif
|
||||||
|
|
||||||
> input
|
&::-webkit-input-placeholder
|
||||||
user-select text
|
color #9eaba8
|
||||||
cursor auto
|
|
||||||
margin 0
|
|
||||||
padding 6px 18px
|
|
||||||
width 14em
|
|
||||||
height 48px
|
|
||||||
font-size 1em
|
|
||||||
line-height calc(48px - 12px)
|
|
||||||
background transparent
|
|
||||||
outline none
|
|
||||||
//border solid 1px #ddd
|
|
||||||
border none
|
|
||||||
border-radius 0
|
|
||||||
transition color 0.5s ease, border 0.5s ease
|
|
||||||
font-family FontAwesome, sans-serif
|
|
||||||
|
|
||||||
&::-webkit-input-placeholder
|
</style>
|
||||||
color #9eaba8
|
<script>
|
||||||
|
@mixin \page
|
||||||
|
|
||||||
script.
|
@onsubmit = (e) ~>
|
||||||
@mixin \page
|
e.prevent-default!
|
||||||
|
@page '/search:' + @refs.q.value
|
||||||
@onsubmit = (e) ~>
|
</script>
|
||||||
e.prevent-default!
|
</mk-ui-header-search>
|
||||||
@page '/search:' + @refs.q.value
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue