diff --git a/gulpfile.ts b/gulpfile.ts index 5246705a115afd1b61be225c4b5d90fd3e980988..677225c3985423c77b61022ccf8a2342cb84979c 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -189,231 +189,6 @@ gulp.task('build:client:scripts', done => { .transform(ls) .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) => { if (file.substr(-4) !== '.tag') return source; @@ -423,6 +198,8 @@ gulp.task('build:client:scripts', done => { .transform(transformify((source, file) => { return source .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\.themeColor/g, `'${config.themeColor}'`) .replace(/CONFIG\.api\.url/g, `'${config.scheme}://api.${config.host}'`) @@ -435,7 +212,6 @@ gulp.task('build:client:scripts', done => { })) .transform(riotify, { - template: 'pug', type: 'livescript', expr: false, 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() .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/')); }); - -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; - } -} diff --git a/src/web/app/auth/tags/form.tag b/src/web/app/auth/tags/form.tag index f5b1555554f38a787cf1422069e253d56278ad0d..21c2339bc7f66c9a838eebeec47a2928efbf1efb 100644 --- a/src/web/app/auth/tags/form.tag +++ b/src/web/app/auth/tags/form.tag @@ -1,126 +1,126 @@ -mk-form - header - h1 - i { app.name } - | ãŒã‚ãªãŸã® - b アカウント - | ã« - b アクセス - | ã™ã‚‹ã“ã¨ã‚’ - b è¨±å¯ - | ã—ã¾ã™ã‹ï¼Ÿ - img(src={ app.icon_url + '?thumbnail&size=64' }) - div.app - section - h2 { app.name } - p.nid { app.name_id } - p.description { app.description } - section - h2 ã“ã®ã‚¢ãƒ—リã¯æ¬¡ã®æ¨©é™ã‚’è¦æ±‚ã—ã¦ã„ã¾ã™: - ul - virtual(each={ p in app.permission }) - li(if={ p == 'account-read' }) アカウントã®æƒ…å ±ã‚’è¦‹ã‚‹ã€‚ - li(if={ p == 'account-write' }) アカウントã®æƒ…å ±ã‚’æ“作ã™ã‚‹ã€‚ - li(if={ p == 'post-write' }) 投稿ã™ã‚‹ã€‚ - li(if={ p == 'like-write' }) ã„ã„ãã—ãŸã‚Šã„ã„ã解除ã™ã‚‹ã€‚ - li(if={ p == 'following-write' }) フォãƒãƒ¼ã—ãŸã‚Šãƒ•ã‚©ãƒãƒ¼è§£é™¤ã™ã‚‹ã€‚ - li(if={ p == 'drive-read' }) ドライブを見る。 - li(if={ p == 'drive-write' }) ドライブをæ“作ã™ã‚‹ã€‚ - li(if={ p == 'notification-read' }) 通知を見る。 - li(if={ p == 'notification-write' }) 通知をæ“作ã™ã‚‹ã€‚ - - div.action - button(onclick={ cancel }) ã‚ャンセル - button(onclick={ accept }) ã‚¢ã‚¯ã‚»ã‚¹ã‚’è¨±å¯ - -style. - display block - - > header - > h1 - margin 0 - padding 32px 32px 20px 32px - font-size 24px - font-weight normal - color #777 - - i - color #77aeca - - &:before - content '「' - - &:after - content 'ã€' +<mk-form> + <header> + <h1><i>{ app.name }</i>ãŒã‚ãªãŸã®<b>アカウント</b>ã«<b>アクセス</b>ã™ã‚‹ã“ã¨ã‚’<b>許å¯</b>ã—ã¾ã™ã‹ï¼Ÿ</h1><img src="{ app.icon_url + '?thumbnail&size=64' }"/> + </header> + <div class="app"> + <section> + <h2>{ app.name }</h2> + <p class="nid">{ app.name_id }</p> + <p class="description">{ app.description }</p> + </section> + <section> + <h2>ã“ã®ã‚¢ãƒ—リã¯æ¬¡ã®æ¨©é™ã‚’è¦æ±‚ã—ã¦ã„ã¾ã™:</h2> + <ul> + <virtual each="{ p in app.permission }"> + <li if="{ p == 'account-read' }">アカウントã®æƒ…å ±ã‚’è¦‹ã‚‹ã€‚</li> + <li if="{ p == 'account-write' }">アカウントã®æƒ…å ±ã‚’æ“作ã™ã‚‹ã€‚</li> + <li if="{ p == 'post-write' }">投稿ã™ã‚‹ã€‚</li> + <li if="{ p == 'like-write' }">ã„ã„ãã—ãŸã‚Šã„ã„ã解除ã™ã‚‹ã€‚</li> + <li if="{ p == 'following-write' }">フォãƒãƒ¼ã—ãŸã‚Šãƒ•ã‚©ãƒãƒ¼è§£é™¤ã™ã‚‹ã€‚</li> + <li if="{ p == 'drive-read' }">ドライブを見る。</li> + <li if="{ p == 'drive-write' }">ドライブをæ“作ã™ã‚‹ã€‚</li> + <li if="{ p == 'notification-read' }">通知を見る。</li> + <li if="{ p == 'notification-write' }">通知をæ“作ã™ã‚‹ã€‚</li> + </virtual> + </ul> + </section> + </div> + <div class="action"> + <button onclick="{ cancel }">ã‚ャンセル</button> + <button onclick="{ accept }">アクセスを許å¯</button> + </div> + <style type="stylus"> + :scope + display block - b - color #666 + > header + > h1 + margin 0 + padding 32px 32px 20px 32px + font-size 24px + font-weight normal + color #777 + + i + color #77aeca + + &:before + content '「' + + &:after + content 'ã€' + + b + 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 - > 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 - content '' - display block - clear both - - > section - float left - width 50% - padding 8px - text-align left - - > h2 - margin 0 - font-size 16px - color #777 - - > .action - padding 16px - - > button - margin 0 8px - - @media (max-width 600px) - > header - > img - box-shadow none - - > .app - box-shadow none - - @media (max-width 500px) - > header - > h1 - font-size 16px - -script. - @mixin \api - - @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 + &:after + content '' + display block + clear both + + > section + float left + width 50% + padding 8px + text-align left + + > h2 + margin 0 + font-size 16px + color #777 + + > .action + padding 16px + + > button + margin 0 8px + + @media (max-width 600px) + > header + > img + box-shadow none + + > .app + box-shadow none + + @media (max-width 500px) + > header + > h1 + font-size 16px + + </style> + <script> + @mixin \api + + @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 + </script> +</mk-form> diff --git a/src/web/app/auth/tags/index.tag b/src/web/app/auth/tags/index.tag index b7017daec6906e52230ec9fde5d29eb9e59d491f..d4818b9bfdea978f33303187e288b3e927c9559d 100644 --- a/src/web/app/auth/tags/index.tag +++ b/src/web/app/auth/tags/index.tag @@ -1,129 +1,136 @@ -mk-index - main(if={ SIGNIN }) - p.fetching(if={ fetching }) - | èªã¿è¾¼ã¿ä¸ - mk-ellipsis - mk-form@form(if={ state == null && !fetching }, session={ session }) - div.denied(if={ state == 'denied' }) - h1 アプリケーションã®é€£æºã‚’ã‚ャンセルã—ã¾ã—ãŸã€‚ - p ã“ã®ã‚¢ãƒ—リãŒã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“。 - div.accepted(if={ state == 'accepted' }) - h1 { session.app.is_authorized ? 'ã“ã®ã‚¢ãƒ—リã¯æ—¢ã«é€£æºæ¸ˆã¿ã§ã™' : 'アプリケーションã®é€£æºã‚’許å¯ã—ã¾ã—ãŸ'} - p(if={ session.app.callback_url }) - | アプリケーションã«æˆ»ã£ã¦ã„ã¾ã™ - mk-ellipsis - p(if={ !session.app.callback_url }) アプリケーションã«æˆ»ã£ã¦ã€ã‚„ã£ã¦ã„ã£ã¦ãã ã•ã„。 - div.error(if={ state == 'fetch-session-error' }) - p セッションãŒå˜åœ¨ã—ã¾ã›ã‚“。 - main.signin(if={ !SIGNIN }) - h1 サインインã—ã¦ãã ã•ã„ - mk-signin - footer - img(src='/_/resources/auth/logo.svg', alt='Misskey') - -style. - display block - - > main - width 100% - 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 +<mk-index> + <main if="{ SIGNIN }"> + <p class="fetching" if="{ fetching }">èªã¿è¾¼ã¿ä¸ + <mk-ellipsis></mk-ellipsis> + </p> + <mk-form ref="form" if="{ state == null && !fetching }" session="{ session }"></mk-form> + <div class="denied" if="{ state == 'denied' }"> + <h1>アプリケーションã®é€£æºã‚’ã‚ャンセルã—ã¾ã—ãŸã€‚</h1> + <p>ã“ã®ã‚¢ãƒ—リãŒã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“。</p> + </div> + <div class="accepted" if="{ state == 'accepted' }"> + <h1>{ session.app.is_authorized ? 'ã“ã®ã‚¢ãƒ—リã¯æ—¢ã«é€£æºæ¸ˆã¿ã§ã™' : 'アプリケーションã®é€£æºã‚’許å¯ã—ã¾ã—ãŸ'}</h1> + <p if="{ session.app.callback_url }">アプリケーションã«æˆ»ã£ã¦ã„ã¾ã™ + <mk-ellipsis></mk-ellipsis> + </p> + <p if="{ !session.app.callback_url }">アプリケーションã«æˆ»ã£ã¦ã€ã‚„ã£ã¦ã„ã£ã¦ãã ã•ã„。</p> + </div> + <div class="error" if="{ state == 'fetch-session-error' }"> + <p>セッションãŒå˜åœ¨ã—ã¾ã›ã‚“。</p> + </div> + </main> + <main class="signin" if="{ !SIGNIN }"> + <h1>サインインã—ã¦ãã ã•ã„</h1> + <mk-signin></mk-signin> + </main> + <footer><img src="/_/resources/auth/logo.svg" alt="Misskey"/></footer> + <style type="stylus"> + :scope display block - width 64px - height 64px - margin 0 auto - -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! - @refs.form.on \denied ~> - @state = \denied + > main + width 100% + 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 + 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! - @refs.form.on \accepted @accepted + @refs.form.on \denied ~> + @state = \denied + @update! - .catch (error) ~> - @fetching = false - @state = \fetch-session-error - @update! + @refs.form.on \accepted @accepted - @accepted = ~> - @state = \accepted - @update! + .catch (error) ~> + @fetching = false + @state = \fetch-session-error + @update! + + @accepted = ~> + @state = \accepted + @update! - if @session.app.callback_url - location.href = @session.app.callback_url + '?token=' + @session.token + if @session.app.callback_url + location.href = @session.app.callback_url + '?token=' + @session.token + </script> +</mk-index> diff --git a/src/web/app/common/tags/copyright.tag b/src/web/app/common/tags/copyright.tag index 0fccf375e84d25cac51bd0170938fff041e81814..c5041935f498b2a0d60d03d79a82d22590f0b8d8 100644 --- a/src/web/app/common/tags/copyright.tag +++ b/src/web/app/common/tags/copyright.tag @@ -1,5 +1,11 @@ -mk-copyright - span (c) syuilo 2014-2017 +<mk-copyright><span>(c) syuilo 2014-2017</span> + <style type="stylus"> + :scope + display block -style. - display block + + + + + </style> +</mk-copyright> diff --git a/src/web/app/common/tags/core-error.tag b/src/web/app/common/tags/core-error.tag index 19ef68bea63e69e64f16a2cbc8b5ffe1b0b98584..0473884497a1f018651ad8d5184cfb03b2c2e7c2 100644 --- a/src/web/app/common/tags/core-error.tag +++ b/src/web/app/common/tags/core-error.tag @@ -1,63 +1,64 @@ -mk-core-error - //i: i.fa.fa-times-circle - img(src='/_/resources/error.jpg', alt='') - h1: mk-ripple-string サーãƒãƒ¼ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ - p.text - | インターãƒãƒƒãƒˆå›žç·šã«å•é¡ŒãŒã‚ã‚‹ã‹ã€ã‚µãƒ¼ãƒãƒ¼ãŒãƒ€ã‚¦ãƒ³ã¾ãŸã¯ãƒ¡ãƒ³ãƒ†ãƒŠãƒ³ã‚¹ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ã—ã°ã‚‰ãã—ã¦ã‹ã‚‰ - a(onclick={ retry }) å†åº¦ãŠè©¦ã— - | ãã ã•ã„。 - p.thanks ã„ã¤ã‚‚Misskeyã‚’ã”利用ã„ãŸã ãã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ +<mk-core-error> + <!--i: i.fa.fa-times-circle--><img src="/_/resources/error.jpg" alt=""/> + <h1> + <mk-ripple-string>サーãƒãƒ¼ã«æŽ¥ç¶šã§ãã¾ã›ã‚“</mk-ripple-string> + </h1> + <p class="text">インターãƒãƒƒãƒˆå›žç·šã«å•é¡ŒãŒã‚ã‚‹ã‹ã€ã‚µãƒ¼ãƒãƒ¼ãŒãƒ€ã‚¦ãƒ³ã¾ãŸã¯ãƒ¡ãƒ³ãƒ†ãƒŠãƒ³ã‚¹ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ã—ã°ã‚‰ãã—ã¦ã‹ã‚‰<a onclick="{ retry }">å†åº¦ãŠè©¦ã—</a>ãã ã•ã„。</p> + <p class="thanks">ã„ã¤ã‚‚Misskeyã‚’ã”利用ã„ãŸã ãã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚</p> + <style type="stylus"> + :scope + position fixed + z-index 16385 + top 0 + left 0 + width 100% + height 100% + text-align center + background #f8f8f8 -style. - position fixed - z-index 16385 - top 0 - left 0 - width 100% - height 100% - text-align center - background #f8f8f8 + > i + display block + margin-top 64px + font-size 5em + color #6998a0 - > i - display block - margin-top 64px - font-size 5em - color #6998a0 + > img + display block + height 200px + margin 64px auto 0 auto + pointer-events none + -ms-user-select none + -moz-user-select none + -webkit-user-select none + user-select none - > img - display block - height 200px - margin 64px auto 0 auto - pointer-events none - -ms-user-select none - -moz-user-select none - -webkit-user-select none - user-select none + > h1 + display block + margin 32px auto 16px auto + font-size 1.5em + color #555 - > h1 - display block - margin 32px auto 16px auto - font-size 1.5em - color #555 + > .text + display block + margin 0 auto + max-width 600px + font-size 1em + color #666 - > .text - display block - margin 0 auto - max-width 600px - font-size 1em - color #666 + > .thanks + display block + margin 32px auto 0 auto + padding 32px 0 32px 0 + max-width 600px + font-size 0.9em + font-style oblique + color #aaa + border-top solid 1px #eee - > .thanks - display block - margin 32px auto 0 auto - padding 32px 0 32px 0 - max-width 600px - font-size 0.9em - font-style oblique - color #aaa - border-top solid 1px #eee - -script. - @retry = ~> - @unmount! - @opts.retry! + </style> + <script> + @retry = ~> + @unmount! + @opts.retry! + </script> +</mk-core-error> diff --git a/src/web/app/common/tags/ellipsis.tag b/src/web/app/common/tags/ellipsis.tag index 47eca62acdef8adbf0e625eadd970c15d5207e24..71755dd8f3491cbbc096194f0ff771c6fe21cbf5 100644 --- a/src/web/app/common/tags/ellipsis.tag +++ b/src/web/app/common/tags/ellipsis.tag @@ -1,25 +1,29 @@ -mk-ellipsis - span . - span . - span . +<mk-ellipsis><span>.</span><span>.</span><span>.</span> + <style type="stylus"> + :scope + display inline -style. - display inline + > span + animation ellipsis 1.4s infinite ease-in-out both - > span - animation ellipsis 1.4s infinite ease-in-out both + &:nth-child(1) + animation-delay 0s - &:nth-child(1) - animation-delay 0s + &:nth-child(2) + animation-delay 0.16s - &:nth-child(2) - animation-delay 0.16s + &:nth-child(3) + animation-delay 0.32s - &:nth-child(3) - animation-delay 0.32s + @keyframes ellipsis + 0%, 80%, 100% + opacity 1 + 40% + opacity 0 - @keyframes ellipsis - 0%, 80%, 100% - opacity 1 - 40% - opacity 0 + + + + + </style> +</mk-ellipsis> diff --git a/src/web/app/common/tags/file-type-icon.tag b/src/web/app/common/tags/file-type-icon.tag index 68b8f95ad75b097e16d39ebaf75b462ce6ea5a70..4569fe81f1cf3f5f50c8a601ddb8caabe1ebd157 100644 --- a/src/web/app/common/tags/file-type-icon.tag +++ b/src/web/app/common/tags/file-type-icon.tag @@ -1,9 +1,11 @@ -mk-file-type-icon - i.fa.fa-file-image-o(if={ kind == 'image' }) +<mk-file-type-icon><i class="fa fa-file-image-o" if="{ kind == 'image' }"></i> + <style type="stylus"> + :scope + display inline -style. - display inline - -script. - @file = @opts.file - @kind = @file.type.split \/ .0 + </style> + <script> + @file = @opts.file + @kind = @file.type.split \/ .0 + </script> +</mk-file-type-icon> diff --git a/src/web/app/common/tags/forkit.tag b/src/web/app/common/tags/forkit.tag index 7205fbe76bbe76ae7639a994117aa1c569acdb5f..5e440554558116f190dd070408277e7206d59db9 100644 --- a/src/web/app/common/tags/forkit.tag +++ b/src/web/app/common/tags/forkit.tag @@ -1,37 +1,44 @@ -mk-forkit - 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) - path(d='M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z') - 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') - -style. - display block - position absolute - top 0 - right 0 - - > a - display block - - > svg +<mk-forkit><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"> + <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path> + <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 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> + </svg></a> + <style type="stylus"> + :scope display block - //fill #151513 - //color #fff - fill $theme-color - color $theme-color-foreground - - .octo-arm - transform-origin 130px 106px - - &:hover - .octo-arm - animation octocat-wave 560ms ease-in-out - - @keyframes octocat-wave - 0%, 100% - transform rotate(0) - 20%, 60% - transform rotate(-25deg) - 40%, 80% - transform rotate(10deg) + position absolute + top 0 + right 0 + + > a + display block + + > svg + display block + //fill #151513 + //color #fff + fill $theme-color + color $theme-color-foreground + + .octo-arm + transform-origin 130px 106px + + &:hover + .octo-arm + animation octocat-wave 560ms ease-in-out + + @keyframes octocat-wave + 0%, 100% + transform rotate(0) + 20%, 60% + transform rotate(-25deg) + 40%, 80% + transform rotate(10deg) + + + + + + </style> +</mk-forkit> diff --git a/src/web/app/common/tags/introduction.tag b/src/web/app/common/tags/introduction.tag index 99df485674359c126e75a1ef2abbe97285ed016a..cfeeb24aced20fc79d3879cb87c87caa4c427811 100644 --- a/src/web/app/common/tags/introduction.tag +++ b/src/web/app/common/tags/introduction.tag @@ -1,22 +1,29 @@ -mk-introduction - article - h1 Misskeyã¨ã¯ï¼Ÿ - <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>ç„¡æ–™ã§èª°ã§ã‚‚利用ã§ãã€åºƒå‘Šã¯ä¸€åˆ‡æŽ²è¼‰ã—ã¦ã„ã¾ã›ã‚“。</p> - <p><a href={ CONFIG.urls.about } target="_blank">ã‚‚ã£ã¨çŸ¥ã‚ŠãŸã„æ–¹ã¯ã“ã¡ã‚‰</a></p> +<mk-introduction> + <article> + <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>Twitter, Facebook, LINE, Google+ ãªã©ã‚’<del>パクã£ã¦</del><i>å‚考ã«ã—ã¦</i>ã„ã¾ã™ã€‚</p> +<p>ç„¡æ–™ã§èª°ã§ã‚‚利用ã§ãã€åºƒå‘Šã¯ä¸€åˆ‡æŽ²è¼‰ã—ã¦ã„ã¾ã›ã‚“。</p> +<p><a href="{ CONFIG.urls.about }" target="_blank">ã‚‚ã£ã¨çŸ¥ã‚ŠãŸã„æ–¹ã¯ã“ã¡ã‚‰</a></p> + </article> + <style type="stylus"> + :scope + display block -style. - display block + h1 + margin 0 + text-align center + font-size 1.2em - h1 - margin 0 - text-align center - font-size 1.2em + p + margin 16px 0 - p - margin 16px 0 + &:last-child + margin 0 + text-align center - &:last-child - margin 0 - text-align center + + + + + </style> +</mk-introduction> diff --git a/src/web/app/common/tags/number.tag b/src/web/app/common/tags/number.tag index 589c747b3545b2d1dea3d1f5035cbc05d525f079..3b9879655e113178c517253722896bbfffd158cd 100644 --- a/src/web/app/common/tags/number.tag +++ b/src/web/app/common/tags/number.tag @@ -1,15 +1,18 @@ -mk-number +<mk-number> + <style type="stylus"> + :scope + display inline -style. - display inline + </style> + <script> + @on \mount ~> + # ãƒã‚°ï¼Ÿ https://github.com/riot/riot/issues/2103 + #value = @opts.value + value = @opts.riot-value + max = @opts.max -script. - @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 - if max? then if value > max then value = max - - @root.innerHTML = value.to-locale-string! + @root.innerHTML = value.to-locale-string! + </script> +</mk-number> diff --git a/src/web/app/common/tags/raw.tag b/src/web/app/common/tags/raw.tag index 131826e5970af417aec4fe519d440f4b10f852c3..ee7318a9f2c48ab0387a912868ed0b4c6c68a737 100644 --- a/src/web/app/common/tags/raw.tag +++ b/src/web/app/common/tags/raw.tag @@ -1,7 +1,8 @@ -mk-raw +<mk-raw> + <style type="stylus"> + :scope + display inline -style. - display inline - -script. - @root.innerHTML = @opts.content + </style> + <script>@root.innerHTML = @opts.content</script> +</mk-raw> diff --git a/src/web/app/common/tags/ripple-string.tag b/src/web/app/common/tags/ripple-string.tag index 3be6903369312c85a3932eaa09b31b8efc7cb41e..2afd2b9ff32e7e2325b636307f31b40a3eb911f4 100644 --- a/src/web/app/common/tags/ripple-string.tag +++ b/src/web/app/common/tags/ripple-string.tag @@ -1,24 +1,26 @@ -mk-ripple-string - <yield/> +<mk-ripple-string><yield/> + <style type="stylus"> + :scope + display inline -style. - display inline + > span + animation ripple-string 5s infinite ease-in-out both - > span - animation ripple-string 5s infinite ease-in-out both + @keyframes ripple-string + 0%, 50%, 100% + opacity 1 + 25% + opacity 0.5 - @keyframes ripple-string - 0%, 50%, 100% - opacity 1 - 25% - opacity 0.5 - -script. - @on \mount ~> - text = @root.innerHTML - @root.innerHTML = '' - (text.split '').for-each (c, i) ~> - ce = document.create-element \span - ce.innerHTML = c - ce.style.animation-delay = (i / 10) + 's' - @root.append-child ce + </style> + <script> + @on \mount ~> + text = @root.innerHTML + @root.innerHTML = '' + (text.split '').for-each (c, i) ~> + ce = document.create-element \span + ce.innerHTML = c + ce.style.animation-delay = (i / 10) + 's' + @root.append-child ce + </script> +</mk-ripple-string> diff --git a/src/web/app/common/tags/signin.tag b/src/web/app/common/tags/signin.tag index 6f4013b1cbccd1a411de7fea7596febc8feb75e6..dc5faca08d2d583053c86d8239dda3eff00bf50b 100644 --- a/src/web/app/common/tags/signin.tag +++ b/src/web/app/common/tags/signin.tag @@ -1,136 +1,131 @@ -mk-signin - form(onsubmit={ onsubmit }, class={ signing: signing }) - label.user-name - input@username( - type='text' - pattern='^[a-zA-Z0-9\-]+$' - placeholder='ユーザーå' - autofocus - required - oninput={ oninput }) - i.fa.fa-at - label.password - 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 +<mk-signin> + <form class="{ signing: signing }" onsubmit="{ onsubmit }"> + <label class="user-name"> + <input ref="username" type="text" pattern="^[a-zA-Z0-9-]+$" placeholder="ユーザーå" autofocus="autofocus" required="required" oninput="{ oninput }"/><i class="fa fa-at"></i> + </label> + <label class="password"> + <input ref="password" type="password" placeholder="パスワード" required="required"/><i class="fa fa-lock"></i> + </label> + <button type="submit" disabled="{ signing }">{ signing ? 'ã‚„ã£ã¦ã„ã¾ã™...' : 'サインイン' }</button> + </form> + <style type="stylus"> + :scope display block - margin 12px 0 - i + > form 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 - - input[type=text] - input[type=password] - 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 - - &:hover - background rgba(255, 255, 255, 0.7) - border-color #ddd - - & + i - color #797776 - - &:focus - background #fff - border-color #ccc - - & + i - color #797776 - - [type=submit] - cursor pointer - 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 - color $theme-color - transition all .2s ease - - &:focus - color $theme-color - transition all .2s ease - - &:active - color darken($theme-color, 30%) - transition all .2s ease - - &:disabled - opacity 0.7 - -script. - @mixin \api - - @user = null - @signing = false - - @oninput = ~> - @api \users/show do - username: @refs.username.value - .then (user) ~> - @user = user - @trigger \user user + z-index 2 + + &.signing + &, * + cursor wait !important + + label + display block + margin 12px 0 + + i + 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 + + input[type=text] + input[type=password] + 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 + + &:hover + background rgba(255, 255, 255, 0.7) + border-color #ddd + + & + i + color #797776 + + &:focus + background #fff + border-color #ccc + + & + i + color #797776 + + [type=submit] + cursor pointer + 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 + color $theme-color + transition all .2s ease + + &:focus + color $theme-color + transition all .2s ease + + &:active + color darken($theme-color, 30%) + transition all .2s ease + + &:disabled + opacity 0.7 + + </style> + <script> + @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! - @onsubmit = (e) ~> - e.prevent-default! - - @signing = true - @update! - - @api \signin do - username: @refs.username.value - password: @refs.password.value - .then ~> - location.reload! - .catch ~> - alert 'something happened' - @signing = false - @update! - - false + @api \signin do + username: @refs.username.value + password: @refs.password.value + .then ~> + location.reload! + .catch ~> + alert 'something happened' + @signing = false + @update! + + false + </script> +</mk-signin> diff --git a/src/web/app/common/tags/signup.tag b/src/web/app/common/tags/signup.tag index 9b28d7d1ff6d4616403654c27a6e0c894e6b20df..c07b27fb1995f1927bdc7a9156780f6bf94bb8d1 100644 --- a/src/web/app/common/tags/signup.tag +++ b/src/web/app/common/tags/signup.tag @@ -1,352 +1,293 @@ -mk-signup - form(onsubmit={ onsubmit }, autocomplete='off') - label.username - p.caption - i.fa.fa-at - | ユーザーå - input@username( - type='text' - pattern='^[a-zA-Z0-9\-]{3,20}$' - placeholder='a~zã€A~Zã€0~9ã€-' - autocomplete='off' - required - onkeyup={ on-change-username }) - - 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 } - - p.info(if={ username-state == 'wait' }, style='color:#999') - i.fa.fa-fw.fa-spinner.fa-pulse - | 確èªã—ã¦ã„ã¾ã™... - p.info(if={ username-state == 'ok' }, style='color:#3CB7B5') - i.fa.fa-fw.fa-check - | 利用ã§ãã¾ã™ - p.info(if={ username-state == 'unavailable' }, style='color:#FF1161') - i.fa.fa-fw.fa-exclamation-triangle - | æ—¢ã«åˆ©ç”¨ã•ã‚Œã¦ã„ã¾ã™ - p.info(if={ username-state == 'error' }, style='color:#FF1161') - i.fa.fa-fw.fa-exclamation-triangle - | 通信エラー - p.info(if={ username-state == 'invalid-format' }, style='color:#FF1161') - i.fa.fa-fw.fa-exclamation-triangle - | a~zã€A~Zã€0~9ã€-(ãƒã‚¤ãƒ•ãƒ³)ãŒä½¿ãˆã¾ã™ - p.info(if={ username-state == 'min-range' }, style='color:#FF1161') - i.fa.fa-fw.fa-exclamation-triangle - | 3æ–‡å—以上ã§ãŠé¡˜ã„ã—ã¾ã™ï¼ - p.info(if={ username-state == 'max-range' }, style='color:#FF1161') - i.fa.fa-fw.fa-exclamation-triangle - | 20æ–‡å—以内ã§ãŠé¡˜ã„ã—ã¾ã™ - - label.password - p.caption - i.fa.fa-lock - | パスワード - 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 +<mk-signup> + <form onsubmit="{ onsubmit }" autocomplete="off"> + <label class="username"> + <p class="caption"><i class="fa fa-at"></i>ユーザーå</p> + <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> + <p class="info" if="{ usernameState == 'wait' }" style="color:#999"><i class="fa fa-fw fa-spinner fa-pulse"></i>確èªã—ã¦ã„ã¾ã™...</p> + <p class="info" if="{ usernameState == 'ok' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>利用ã§ãã¾ã™</p> + <p class="info" if="{ usernameState == 'unavailable' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>æ—¢ã«åˆ©ç”¨ã•ã‚Œã¦ã„ã¾ã™</p> + <p class="info" if="{ usernameState == 'error' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>通信エラー</p> + <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> + <p class="info" if="{ usernameState == 'min-range' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>3æ–‡å—以上ã§ãŠé¡˜ã„ã—ã¾ã™ï¼</p> + <p class="info" if="{ usernameState == 'max-range' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>20æ–‡å—以内ã§ãŠé¡˜ã„ã—ã¾ã™</p> + </label> + <label class="password"> + <p class="caption"><i class="fa fa-lock"></i>パスワード</p> + <input ref="password" type="password" placeholder="8æ–‡å—以上を推奨ã—ã¾ã™" autocomplete="off" required="required" onkeyup="{ onChangePassword }"/> + <div class="meter" if="{ passwordStrength != '' }" data-strength="{ passwordStrength }"> + <div class="value" ref="passwordMetar"></div> + </div> + <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 class="info" if="{ passwordStrength == 'high' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>å¼·ã„パスワード</p> + </label> + <label class="retype-password"> + <p class="caption"><i class="fa fa-lock"></i>パスワード(å†å…¥åŠ›)</p> + <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 class="info" if="{ passwordRetypeState == 'not-match' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>一致ã—ã¦ã„ã¾ã›ã‚“</p> + </label> + <label class="recaptcha"> + <p class="caption"><i class="fa fa-toggle-on" if="{ recaptchaed }"></i><i class="fa fa-toggle-off" if="{ !recaptchaed }"></i>èªè¨¼</p> + <div class="g-recaptcha" data-callback="onRecaptchaed" data-expired-callback="onRecaptchaExpired" data-sitekey="{ CONFIG.recaptcha.siteKey }"></div> + </label> + <label class="agree-tou"> + <input name="agree-tou" type="checkbox" autocomplete="off" required="required"/> + <p><a href="{ CONFIG.urls.about + '/tou' }" target="_blank">利用è¦ç´„</a>ã«åŒæ„ã™ã‚‹</p> + </label> + <button onclick="{ onsubmit }">アカウント作æˆ</button> + </form> + <style type="stylus"> + :scope display block - margin 16px 0 + min-width 302px + overflow hidden - > .caption - margin 0 0 4px 0 - color #828888 - font-size 0.95em + > form - > i - 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 + label display block - margin 4px 8px 0 4px - font-size 0.8em - color #888 + margin 16px 0 - &:empty - display none + > .caption + margin 0 0 4px 0 + color #828888 + font-size 0.95em - &:not(:empty) + .info - margin-top 0 + > i + margin-right 0.25em + color #96adac - &.password - .meter - display block - margin-top 8px + > .info + display block + margin 4px 0 + font-size 0.8em + + > i + margin-right 0.3em + + &.username + .profile-page-url-preview + display block + margin 4px 8px 0 4px + font-size 0.8em + color #888 + + &:empty + display none + + &:not(:empty) + .info + margin-top 0 + + &.password + .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 + width 0% + height 100% + background transparent + border-radius 4px + transition all 0.1s ease + + [type=text], [type=password] + user-select text + display inline-block + cursor auto + padding 0 12px + margin 0 width 100% - height 8px - - &[data-strength=''] - display none + 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 + border-color rgba(0, 0, 0, 0.2) + transition all .1s ease + + &:focus + color $theme-color !important + 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 + opacity 0.5 + + .agree-tou + padding 4px + border-radius 4px + + &: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 - &[data-strength='low'] - > .value - background #d73612 + &:hover + background lighten($theme-color, 5%) - &[data-strength='medium'] - > .value - background #d7ca12 + &:active + background darken($theme-color, 5%) - &[data-strength='high'] - > .value - background #61bb22 + </style> + <script> + @mixin \api + @mixin \get-password-strength - > .value - display block - width 0% - height 100% - background transparent - border-radius 4px - transition all 0.1s ease - - [type=text], [type=password] - 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 - - &:hover - border-color rgba(0, 0, 0, 0.2) - transition all .1s ease - - &:focus - color $theme-color !important - 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 - opacity 0.5 - - .agree-tou - padding 4px - border-radius 4px - - &: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%) - -script. - @mixin \api - @mixin \get-password-strength - - @username-state = null - @password-strength = '' - @password-retype-state = null - @recaptchaed = false - - window.on-recaptchaed = ~> - @recaptchaed = true - @update! - - window.on-recaptcha-expired = ~> + @username-state = null + @password-strength = '' + @password-retype-state = null @recaptchaed = false - @update! - - @on \mount ~> - head = (document.get-elements-by-tag-name \head).0 - 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 + window.on-recaptchaed = ~> + @recaptchaed = true + @update! - if username == '' - @username-state = null + window.on-recaptcha-expired = ~> + @recaptchaed = false @update! - return - err = switch - | not username.match /^[a-zA-Z0-9\-]+$/ => \invalid-format - | username.length < 3chars => \min-range - | username.length > 20chars => \max-range - | _ => null + @on \mount ~> + head = (document.get-elements-by-tag-name \head).0 + script = document.create-element \script + ..set-attribute \src \https://www.google.com/recaptcha/api.js + head.append-child script - if err? - @username-state = err - @update! - else - @username-state = \wait - @update! + @on-change-username = ~> + username = @refs.username.value - @api \username/available do - username: username - .then (result) ~> - if result.available - @username-state = \ok - else - @username-state = \unavailable - @update! - .catch (err) ~> - @username-state = \error + if username == '' + @username-state = null @update! + return - @on-change-password = ~> - password = @refs.password.value + err = switch + | not username.match /^[a-zA-Z0-9\-]+$/ => \invalid-format + | username.length < 3chars => \min-range + | username.length > 20chars => \max-range + | _ => null - if password == '' - @password-strength = '' - return - - strength = @get-password-strength password + if err? + @username-state = err + @update! + else + @username-state = \wait + @update! - if strength > 0.3 - @password-strength = \medium - if strength > 0.7 - @password-strength = \high - else - @password-strength = \low + @api \username/available do + username: username + .then (result) ~> + if result.available + @username-state = \ok + else + @username-state = \unavailable + @update! + .catch (err) ~> + @username-state = \error + @update! + + @on-change-password = ~> + password = @refs.password.value + + if password == '' + @password-strength = '' + return + + strength = @get-password-strength password + + if strength > 0.3 + @password-strength = \medium + if strength > 0.7 + @password-strength = \high + else + @password-strength = \low - @update! + @update! - @refs.password-metar.style.width = (strength * 100) + \% + @refs.password-metar.style.width = (strength * 100) + \% - @on-change-password-retype = ~> - password = @refs.password.value - retyped-password = @refs.password-retype.value + @on-change-password-retype = ~> + password = @refs.password.value + retyped-password = @refs.password-retype.value - if retyped-password == '' - @password-retype-state = null - return + if retyped-password == '' + @password-retype-state = null + return - if password == retyped-password - @password-retype-state = \match - else - @password-retype-state = \not-match + if password == retyped-password + @password-retype-state = \match + else + @password-retype-state = \not-match - @onsubmit = (e) ~> - e.prevent-default! + @onsubmit = (e) ~> + e.prevent-default! - username = @refs.username.value - password = @refs.password.value + username = @refs.username.value + password = @refs.password.value - locker = document.body.append-child document.create-element \mk-locker + locker = document.body.append-child document.create-element \mk-locker - @api \signup do - username: username - password: password - 'g-recaptcha-response': grecaptcha.get-response! - .then ~> - @api \signin do + @api \signup do username: username password: password + 'g-recaptcha-response': grecaptcha.get-response! .then ~> - location.href = CONFIG.url - .catch ~> - alert '何らã‹ã®åŽŸå› ã«ã‚ˆã‚Šã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚å†åº¦ãŠè©¦ã—ãã ã•ã„。' - - grecaptcha.reset! - @recaptchaed = false - - locker.parent-node.remove-child locker - - false + @api \signin do + username: username + password: password + .then ~> + location.href = CONFIG.url + .catch ~> + alert '何らã‹ã®åŽŸå› ã«ã‚ˆã‚Šã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚å†åº¦ãŠè©¦ã—ãã ã•ã„。' + + grecaptcha.reset! + @recaptchaed = false + + locker.parent-node.remove-child locker + + false + </script> +</mk-signup> diff --git a/src/web/app/common/tags/special-message.tag b/src/web/app/common/tags/special-message.tag index 5a6d5787eaca985ae64da8451aa6ffc40277955a..ffba09c2dac4a6bf8cb38a61b4612b293b16e7e7 100644 --- a/src/web/app/common/tags/special-message.tag +++ b/src/web/app/common/tags/special-message.tag @@ -1,24 +1,27 @@ -mk-special-message - p(if={ m == 1 && d == 1 }) Happy New Year! - p(if={ m == 12 && d == 25 }) Merry Christmas! +<mk-special-message> + <p if="{ m == 1 && d == 1 }">Happy New Year! </p> + <p if="{ m == 12 && d == 25 }">Merry Christmas!</p> + <style type="stylus"> + :scope + display block -style. - display block + &:empty + display none - &:empty - display none + > p + margin 0 + padding 4px + text-align center + font-size 14px + font-weight bold + text-transform uppercase + color #fff + background #ff1036 - > p - margin 0 - padding 4px - text-align center - font-size 14px - font-weight bold - text-transform uppercase - color #fff - background #ff1036 - -script. - now = new Date! - @d = now.get-date! - @m = now.get-month! + 1 + </style> + <script> + now = new Date! + @d = now.get-date! + @m = now.get-month! + 1 + </script> +</mk-special-message> diff --git a/src/web/app/common/tags/time.tag b/src/web/app/common/tags/time.tag index 52ad89a44f5db230d74149d9aaa6eff808aec4f9..5456adb0b62d65aae1372605bd81647b0b48165c 100644 --- a/src/web/app/common/tags/time.tag +++ b/src/web/app/common/tags/time.tag @@ -1,43 +1,41 @@ -mk-time - time(datetime={ opts.time }) - span(if={ mode == 'relative' }) { relative } - span(if={ mode == 'absolute' }) { absolute } - span(if={ mode == 'detail' }) { absolute } ({ relative }) +<mk-time> + <time datetime="{ opts.time }"><span if="{ mode == 'relative' }">{ relative }</span><span if="{ mode == 'absolute' }">{ absolute }</span><span if="{ mode == 'detail' }">{ absolute } ({ relative })</span></time> + <script> + @time = new Date @opts.time + @mode = @opts.mode || \relative + @tickid = null -script. - @time = new Date @opts.time - @mode = @opts.mode || \relative - @tickid = null + @absolute = + @time.get-full-year! + \å¹´ + + @time.get-month! + 1 + \月 + + @time.get-date! + \æ—¥ + + ' ' + + @time.get-hours! + \時 + + @time.get-minutes! + \分 - @absolute = - @time.get-full-year! + \å¹´ + - @time.get-month! + 1 + \月 + - @time.get-date! + \æ—¥ + - ' ' + - @time.get-hours! + \時 + - @time.get-minutes! + \分 + @on \mount ~> + if @mode == \relative or @mode == \detail + @tick! + @tickid = set-interval @tick, 1000ms - @on \mount ~> - if @mode == \relative or @mode == \detail - @tick! - @tickid = set-interval @tick, 1000ms + @on \unmount ~> + if @mode == \relative or @mode == \detail + clear-interval @tickid - @on \unmount ~> - if @mode == \relative or @mode == \detail - clear-interval @tickid - - @tick = ~> - now = new Date! - ago = (now - @time) / 1000ms - @relative = switch - | ago >= 31536000s => ~~(ago / 31536000s) + 'å¹´å‰' - | ago >= 2592000s => ~~(ago / 2592000s) + 'ヶ月å‰' - | ago >= 604800s => ~~(ago / 604800s) + '週間å‰' - | ago >= 86400s => ~~(ago / 86400s) + 'æ—¥å‰' - | ago >= 3600s => ~~(ago / 3600s) + '時間å‰' - | ago >= 60s => ~~(ago / 60s) + '分å‰' - | ago >= 10s => ~~(ago % 60s) + '秒å‰' - | ago >= 0s => 'ãŸã£ãŸä»Š' - | ago < 0s => '未æ¥' - | _ => 'ãªãžã®ã˜ã‹ã‚“' - @update! + @tick = ~> + now = new Date! + ago = (now - @time) / 1000ms + @relative = switch + | ago >= 31536000s => ~~(ago / 31536000s) + 'å¹´å‰' + | ago >= 2592000s => ~~(ago / 2592000s) + 'ヶ月å‰' + | ago >= 604800s => ~~(ago / 604800s) + '週間å‰' + | ago >= 86400s => ~~(ago / 86400s) + 'æ—¥å‰' + | ago >= 3600s => ~~(ago / 3600s) + '時間å‰' + | ago >= 60s => ~~(ago / 60s) + '分å‰' + | ago >= 10s => ~~(ago % 60s) + '秒å‰' + | ago >= 0s => 'ãŸã£ãŸä»Š' + | ago < 0s => '未æ¥' + | _ => 'ãªãžã®ã˜ã‹ã‚“' + @update! + </script> +</mk-time> diff --git a/src/web/app/common/tags/uploader.tag b/src/web/app/common/tags/uploader.tag index 6d4e9b6363e48f10899fc1862284dc980ffb88d7..6a081ddaf0dc07d578d6d5a25f6c17c476a48eae 100644 --- a/src/web/app/common/tags/uploader.tag +++ b/src/web/app/common/tags/uploader.tag @@ -1,201 +1,195 @@ -mk-uploader - ol(if={ uploads.length > 0 }) - li(each={ uploads }) - div.img(style='background-image: url({ img })') - p.name - i.fa.fa-spinner.fa-pulse - | { name } - p.status - span.initing(if={ progress == undefined }) - | å¾…æ©Ÿä¸ - mk-ellipsis - span.kb(if={ progress != undefined }) - | { String(Math.floor(progress.value / 1024)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') } - i KB - = ' / ' - | { 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 +<mk-uploader> + <ol if="{ uploads.length > 0 }"> + <li each="{ uploads }"> + <div class="img" style="background-image: url({ img })"></div> + <p class="name"><i class="fa fa-spinner fa-pulse"></i>{ name }</p> + <p class="status"><span class="initing" if="{ progress == undefined }">å¾…æ©Ÿä¸ + <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> + <progress if="{ progress != undefined && progress.value != progress.max }" value="{ progress.value }" max="{ progress.max }"></progress> + <div class="progress initing" if="{ progress == undefined }"></div> + <div class="progress waiting" if="{ progress != undefined && progress.value == progress.max }"></div> + </li> + </ol> + <style type="stylus"> + :scope 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 + overflow auto - &:first-child - margin 0 - box-shadow none - border-top none - - > .img - 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 - padding 0 - max-width 256px - font-size 0.8em - color rgba($theme-color, 0.7) - white-space nowrap - text-overflow ellipsis - overflow hidden + &:empty + display none - > i - margin-right 4px - - > .status + > ol display block - position absolute - top 0 - right 0 margin 0 padding 0 - font-size 0.8em - - > .initing - color rgba($theme-color, 0.5) - - > .kb - color rgba($theme-color, 0.5) - - > .percentage - display inline-block - width 48px - text-align right - - color rgba($theme-color, 0.7) - - &:after - content '%' - - > progress - 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 - - &::-webkit-progress-value - background $theme-color - - &::-webkit-progress-bar - background rgba($theme-color, 0.1) - - > .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;} - -script. - @mixin \i - - @uploads = [] - - - @upload = (file, folder) ~> - id = Math.random! - - ctx = - id: id - name: file.name || \untitled - progress: undefined - - @uploads.push ctx - @trigger \change-uploads @uploads - @update! - - reader = new FileReader! - reader.onload = (e) ~> - ctx.img = e.target.result + list-style none + + > li + 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 + + &:first-child + margin 0 + box-shadow none + border-top none + + > .img + 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 + padding 0 + max-width 256px + font-size 0.8em + color rgba($theme-color, 0.7) + white-space nowrap + text-overflow ellipsis + overflow hidden + + > i + margin-right 4px + + > .status + display block + position absolute + top 0 + right 0 + margin 0 + padding 0 + font-size 0.8em + + > .initing + color rgba($theme-color, 0.5) + + > .kb + color rgba($theme-color, 0.5) + + > .percentage + display inline-block + width 48px + text-align right + + color rgba($theme-color, 0.7) + + &:after + content '%' + + > progress + 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 + + &::-webkit-progress-value + background $theme-color + + &::-webkit-progress-bar + background rgba($theme-color, 0.1) + + > .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) ~> + id = Math.random! + + ctx = + id: id + name: file.name || \untitled + progress: undefined + + @uploads.push ctx + @trigger \change-uploads @uploads @update! - reader.read-as-data-URL file - data = new FormData! - data.append \i @I.token - data.append \file file + reader = new FileReader! + reader.onload = (e) ~> + ctx.img = e.target.result + @update! + reader.read-as-data-URL file - if folder? - data.append \folder_id folder + data = new FormData! + data.append \i @I.token + data.append \file file - xhr = new XMLHttpRequest! - xhr.open \POST CONFIG.api.url + '/drive/files/create' true - xhr.onload = (e) ~> - drive-file = JSON.parse e.target.response + if folder? + data.append \folder_id folder - @trigger \uploaded drive-file + xhr = new XMLHttpRequest! + xhr.open \POST CONFIG.api.url + '/drive/files/create' true + xhr.onload = (e) ~> + drive-file = JSON.parse e.target.response - @uploads = @uploads.filter (x) -> x.id != id - @trigger \change-uploads @uploads + @trigger \uploaded drive-file - @update! + @uploads = @uploads.filter (x) -> x.id != id + @trigger \change-uploads @uploads - 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 + 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> diff --git a/src/web/app/common/tags/url-preview.tag b/src/web/app/common/tags/url-preview.tag index 605d26bc67096822a7fdb0f543799fdf3a3c1def..860d4d547f0f89b93f60435bee1bdb10278bae30 100644 --- a/src/web/app/common/tags/url-preview.tag +++ b/src/web/app/common/tags/url-preview.tag @@ -1,105 +1,110 @@ -mk-url-preview - a(href={ url }, target='_blank', title={ url }, if={ !loading }) - div.thumbnail(if={ thumbnail }, style={ 'background-image: url(' + thumbnail + ')' }) - article - header: h1 { title } - p { description } - footer - img.icon(if={ icon }, src={ icon }) - p { sitename } - -style. - display block - font-size 16px - - > a - display block - border solid 1px #eee - border-radius 4px - overflow hidden - - &:hover - text-decoration none - border-color #ddd - - > article > header > h1 - text-decoration underline - - > .thumbnail - position absolute - width 100px - height 100% - background-position center - background-size cover - - & + article - left 100px - width calc(100% - 100px) - - > article - padding 16px - - > header - margin-bottom 8px - - > h1 - margin 0 - font-size 1em - color #555 - - > p - margin 0 - color #777 - font-size 0.8em - - > footer - margin-top 8px - - > img - display inline-block - width 16px - heigth 16px - margin-right 4px - vertical-align bottom - - > p - display inline-block - margin 0 - color #666 - font-size 0.8em - line-height 16px - - @media (max-width 500px) - font-size 8px - - > a - border none - - > .thumbnail - width 70px - - & + article - left 70px - width calc(100% - 70px) - - > article - padding 8px - -script. - @mixin \api - - @url = @opts.url - @loading = true - - @on \mount ~> - 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 - - @loading = false - @update! +<mk-url-preview><a href="{ url }" target="_blank" title="{ url }" if="{ !loading }"> + <div class="thumbnail" if="{ thumbnail }" style="{ 'background-image: url(' + thumbnail + ')' }"></div> + <article> + <header> + <h1>{ title }</h1> + </header> + <p>{ description }</p> + <footer><img class="icon" if="{ icon }" src="{ icon }"/> + <p>{ sitename }</p> + </footer> + </article></a> + <style type="stylus"> + :scope + display block + font-size 16px + + > a + display block + border solid 1px #eee + border-radius 4px + overflow hidden + + &:hover + text-decoration none + border-color #ddd + + > article > header > h1 + text-decoration underline + + > .thumbnail + position absolute + width 100px + height 100% + background-position center + background-size cover + + & + article + left 100px + width calc(100% - 100px) + + > article + padding 16px + + > header + margin-bottom 8px + + > h1 + margin 0 + font-size 1em + color #555 + + > p + margin 0 + color #777 + font-size 0.8em + + > footer + margin-top 8px + + > img + display inline-block + width 16px + heigth 16px + margin-right 4px + vertical-align bottom + + > p + display inline-block + margin 0 + color #666 + font-size 0.8em + line-height 16px + + @media (max-width 500px) + font-size 8px + + > a + border none + + > .thumbnail + width 70px + + & + article + left 70px + width calc(100% - 70px) + + > article + padding 8px + + </style> + <script> + @mixin \api + + @url = @opts.url + @loading = true + + @on \mount ~> + 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 + + @loading = false + @update! + </script> +</mk-url-preview> diff --git a/src/web/app/common/tags/url.tag b/src/web/app/common/tags/url.tag index 18892e8108c0e666c7557c2080925942c702d4ba..be7db32c5fc177b32acea7888b958aea8c562f25 100644 --- a/src/web/app/common/tags/url.tag +++ b/src/web/app/common/tags/url.tag @@ -1,50 +1,46 @@ -mk-url - a(href={ url }, target={ opts.target }) - span.schema { schema }// - span.hostname { hostname } - span.port(if={ port != '' }) :{ port } - span.pathname(if={ pathname != '' }) { pathname } - span.query { query } - span.hash { hash } - -style. - > a - &:after - content "\f14c" - display inline-block - padding-left 2px - font-family FontAwesome - font-size .9em - font-weight 400 - font-style normal - - > .schema - opacity 0.5 - - > .hostname - font-weight bold - - > .pathname - opacity 0.8 - - > .query - opacity 0.5 - - > .hash - font-style italic - -script. - @url = @opts.href - - @on \before-mount ~> - parser = document.create-element \a - parser.href = @url - - @schema = parser.protocol - @hostname = parser.hostname - @port = parser.port - @pathname = parser.pathname - @query = parser.search - @hash = parser.hash - - @update! +<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> + <style type="stylus"> + :scope + > a + &:after + content "\f14c" + display inline-block + padding-left 2px + font-family FontAwesome + font-size .9em + font-weight 400 + font-style normal + + > .schema + opacity 0.5 + + > .hostname + font-weight bold + + > .pathname + opacity 0.8 + + > .query + opacity 0.5 + + > .hash + font-style italic + + </style> + <script> + @url = @opts.href + + @on \before-mount ~> + parser = document.create-element \a + parser.href = @url + + @schema = parser.protocol + @hostname = parser.hostname + @port = parser.port + @pathname = parser.pathname + @query = parser.search + @hash = parser.hash + + @update! + </script> +</mk-url> diff --git a/src/web/app/desktop/tags/analog-clock.tag b/src/web/app/desktop/tags/analog-clock.tag index a4cfe5726c950798ee3994b9d43c05f2787465c4..c84accb057893db26a2de6600dc7abb385b51d91 100644 --- a/src/web/app/desktop/tags/analog-clock.tag +++ b/src/web/app/desktop/tags/analog-clock.tag @@ -1,102 +1,105 @@ -mk-analog-clock - canvas@canvas(width='256', height='256') +<mk-analog-clock> + <canvas ref="canvas" width="256" height="256"></canvas> + <style type="stylus"> + :scope + > canvas + display block + width 256px + height 256px -style. - > canvas - display block - width 256px - height 256px + </style> + <script> + @on \mount ~> + @draw! + @clock = set-interval @draw, 1000ms -script. - @on \mount ~> - @draw! - @clock = set-interval @draw, 1000ms + @on \unmount ~> + clear-interval @clock - @on \unmount ~> - clear-interval @clock + @draw = ~> + now = new Date! + s = now.get-seconds! + m = now.get-minutes! + h = now.get-hours! - @draw = ~> - now = new Date! - s = now.get-seconds! - m = now.get-minutes! - h = now.get-hours! + vec2 = (x, y) -> + @x = x + @y = y - vec2 = (x, y) -> - @x = x - @y = y + ctx = @refs.canvas.get-context \2d + canv-w = @refs.canvas.width + 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 - canv-h = @refs.canvas.height - ctx.clear-rect 0, 0, canv-w, canv-h + # 背景 + center = (Math.min (canv-w / 2), (canv-h / 2)) + line-start = center * 0.90 + line-end-short = center * 0.87 + 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)) - line-start = center * 0.90 - 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 + # 分 + angle = Math.PI * (m + s / 60) / 30 + length = (Math.min canv-w, canv-h) / 2.6 uv = new vec2 (Math.sin angle), (-Math.cos angle) ctx.begin-path! - ctx.line-width = 1 + ctx.stroke-style = \#ffffff + ctx.line-width = 2 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 + (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! - # 分 - angle = Math.PI * (m + s / 60) / 30 - length = (Math.min canv-w, canv-h) / 2.6 - uv = new vec2 (Math.sin angle), (-Math.cos angle) - ctx.begin-path! - ctx.stroke-style = \#ffffff - ctx.line-width = 2 - 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! - - # 時 - angle = Math.PI * (h % 12 + m / 60) / 6 - length = (Math.min canv-w, canv-h) / 4 - uv = new vec2 (Math.sin angle), (-Math.cos angle) - ctx.begin-path! - #ctx.stroke-style = \#ffffff - ctx.stroke-style = CONFIG.theme-color - ctx.line-width = 2 - 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! + # 時 + angle = Math.PI * (h % 12 + m / 60) / 6 + length = (Math.min canv-w, canv-h) / 4 + uv = new vec2 (Math.sin angle), (-Math.cos angle) + ctx.begin-path! + #ctx.stroke-style = \#ffffff + ctx.stroke-style = CONFIG.theme-color + ctx.line-width = 2 + 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! - # 秒 - 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! + # 秒 + 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! + </script> +</mk-analog-clock> diff --git a/src/web/app/desktop/tags/autocomplete-suggestion.tag b/src/web/app/desktop/tags/autocomplete-suggestion.tag index 13d9df691462273c7d0a45c9ef6cbd5729214478..ecebf26a322e77e0038f483624d4f729802c03e6 100644 --- a/src/web/app/desktop/tags/autocomplete-suggestion.tag +++ b/src/web/app/desktop/tags/autocomplete-suggestion.tag @@ -1,182 +1,183 @@ -mk-autocomplete-suggestion - ol.users@users(if={ users.length > 0 }) - li(each={ users }, onclick={ parent.on-click }, onkeydown={ parent.on-keydown }, tabindex='-1') - img.avatar(src={ avatar_url + '?thumbnail&size=32' }, alt='') - span.name { name } - span.username @{ username } - -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 +<mk-autocomplete-suggestion> + <ol class="users" ref="users" if="{ users.length > 0 }"> + <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> + </ol> + <style type="stylus"> + :scope display block - padding 4px 12px - white-space nowrap + position absolute + z-index 65535 + margin-top calc(1em + 8px) overflow hidden - font-size 0.9em - color rgba(0, 0, 0, 0.8) - cursor default - - &, * - user-select none - - &:hover - &[data-selected='true'] - 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 28px - min-height 28px - max-width 28px - max-height 28px - margin 0 8px 0 0 - border-radius 100% - - .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) - -script. - @mixin \api - - @q = @opts.q - @textarea = @opts.textarea - @loading = true - @users = [] - @select = -1 - - @on \mount ~> - @textarea.add-event-listener \keydown @on-keydown - - all = document.query-selector-all 'body *' - Array.prototype.for-each.call all, (el) ~> - el.add-event-listener \mousedown @mousedown - - @api \users/search_by_username do - query: @q - limit: 30users - .then (users) ~> - @users = users - @loading = false - @update! - .catch (err) ~> - console.error err - - @on \unmount ~> - @textarea.remove-event-listener \keydown @on-keydown - - all = document.query-selector-all 'body *' - Array.prototype.for-each.call all, (el) ~> - el.remove-event-listener \mousedown @mousedown - - @mousedown = (e) ~> - if (!contains @root, e.target) and (@root != e.target) - @close! - - @on-click = (e) ~> - @complete e.item - - @on-keydown = (e) ~> - key = e.which - switch (key) - | 10, 13 => # Key[ENTER] - if @select != -1 + 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 + padding 4px 12px + white-space nowrap + overflow hidden + font-size 0.9em + color rgba(0, 0, 0, 0.8) + cursor default + + &, * + user-select none + + &:hover + &[data-selected='true'] + 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 28px + min-height 28px + max-width 28px + max-height 28px + margin 0 8px 0 0 + border-radius 100% + + .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) + + </style> + <script> + @mixin \api + + @q = @opts.q + @textarea = @opts.textarea + @loading = true + @users = [] + @select = -1 + + @on \mount ~> + @textarea.add-event-listener \keydown @on-keydown + + all = document.query-selector-all 'body *' + Array.prototype.for-each.call all, (el) ~> + el.add-event-listener \mousedown @mousedown + + @api \users/search_by_username do + query: @q + limit: 30users + .then (users) ~> + @users = users + @loading = false + @update! + .catch (err) ~> + console.error err + + @on \unmount ~> + @textarea.remove-event-listener \keydown @on-keydown + + all = document.query-selector-all 'body *' + Array.prototype.for-each.call all, (el) ~> + el.remove-event-listener \mousedown @mousedown + + @mousedown = (e) ~> + if (!contains @root, e.target) and (@root != e.target) + @close! + + @on-click = (e) ~> + @complete e.item + + @on-keydown = (e) ~> + 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! - @complete @users[@select] - else @close! - | 27 => # Key[ESC] - e.prevent-default! - e.stop-propagation! - @close! - | 38 => # Key[↑] - if @select != -1 + | 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-prev! - else + @select-next! + | _ => @close! - | 9, 40 => # Key[TAB] or Key[↓] - e.prevent-default! - e.stop-propagation! - @select-next! - | _ => - @close! - @select-next = ~> - @select++ + @select-next = ~> + @select++ - if @select >= @users.length - @select = 0 + if @select >= @users.length + @select = 0 - @apply-select! + @apply-select! - @select-prev = ~> - @select-- + @select-prev = ~> + @select-- - if @select < 0 - @select = @users.length - 1 + if @select < 0 + @select = @users.length - 1 - @apply-select! + @apply-select! - @apply-select = ~> - @refs.users.children.for-each (el) ~> - el.remove-attribute \data-selected + @apply-select = ~> + @refs.users.children.for-each (el) ~> + el.remove-attribute \data-selected - @refs.users.children[@select].set-attribute \data-selected \true - @refs.users.children[@select].focus! + @refs.users.children[@select].set-attribute \data-selected \true + @refs.users.children[@select].focus! - @complete = (user) ~> - @opts.complete user + @complete = (user) ~> + @opts.complete user - @close = ~> - @opts.close! + @close = ~> + @opts.close! - function contains(parent, child) - node = child.parent-node - while node? - if node == parent - return true - 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> diff --git a/src/web/app/desktop/tags/big-follow-button.tag b/src/web/app/desktop/tags/big-follow-button.tag index 636853407ceb6fcb7931566827c43941de1feedc..37c67f07b2667ccf9c34a612d795011f5c494b3c 100644 --- a/src/web/app/desktop/tags/big-follow-button.tag +++ b/src/web/app/desktop/tags/big-follow-button.tag @@ -1,134 +1,127 @@ -mk-big-follow-button - button(if={ !init }, class={ wait: wait, follow: !user.is_following, unfollow: user.is_following }, - onclick={ onclick }, - disabled={ wait }, - title={ user.is_following ? 'フォãƒãƒ¼è§£é™¤' : 'フォãƒãƒ¼ã™ã‚‹' }) - span(if={ !wait && user.is_following }) - 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. - display block - - > button - > .init - display block - cursor pointer - padding 0 - margin 0 - width 100% - line-height 38px - font-size 1em - outline none - border-radius 4px - - * - pointer-events none - - i - margin-right 8px - - &: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 - - &.follow - color #888 - background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) - border solid 1px #e2e2e2 - - &:hover - background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) - border-color #dcdcdc - - &:active - background #ececec - border-color #dcdcdc - - &.unfollow - 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%) - - &: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 - - &.wait - cursor wait !important - opacity 0.7 - -script. - @mixin \api - @mixin \is-promise - @mixin \stream - - @user = null - @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user - @init = true - @wait = false - - @on \mount ~> - @user-promise.then (user) ~> - @user = user - @init = false - @update! - @stream.on \follow @on-stream-follow - @stream.on \unfollow @on-stream-unfollow - - @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 +<mk-big-follow-button> + <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> + <div class="init" if="{ init }"><i class="fa fa-spinner fa-pulse fa-fw"></i></div> + <style type="stylus"> + :scope + display block + + > button + > .init + display block + cursor pointer + padding 0 + margin 0 + width 100% + line-height 38px + font-size 1em + outline none + border-radius 4px + + * + pointer-events none + + i + margin-right 8px + + &: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 + + &.follow + color #888 + background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) + border solid 1px #e2e2e2 + + &:hover + background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) + border-color #dcdcdc + + &:active + background #ececec + border-color #dcdcdc + + &.unfollow + 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%) + + &: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 + + &.wait + cursor wait !important + opacity 0.7 + + </style> + <script> + @mixin \api + @mixin \is-promise + @mixin \stream + + @user = null + @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user + @init = true + @wait = false + + @on \mount ~> + @user-promise.then (user) ~> + @user = user + @init = false @update! - else - @api \following/create do - user_id: @user.id - .then ~> - @user.is_following = true - .catch (err) -> - console.error err - .then ~> - @wait = false + @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! + 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> diff --git a/src/web/app/desktop/tags/contextmenu.tag b/src/web/app/desktop/tags/contextmenu.tag index 7c3c7b8a240e30264723e87d92a5280d5180ec71..c82a1e1e3ab2bbaa9f83a9f12545c771c3b20751 100644 --- a/src/web/app/desktop/tags/contextmenu.tag +++ b/src/web/app/desktop/tags/contextmenu.tag @@ -1,138 +1,139 @@ -mk-contextmenu - | <yield /> - -style. - $width = 240px - $item-height = 38px - $padding = 10px - - display none - position fixed - top 0 - 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) - - ul - display block - margin 0 - padding $padding 0 - list-style none - - li - display block - - &.separator - margin-top $padding - padding-top $padding - border-top solid 1px #eee - - &.has-child - > p - cursor default - - > i:last-child - position absolute - top 0 - right 8px - line-height $item-height - - &:hover > ul - visibility visible +<mk-contextmenu><yield /> + <style type="stylus"> + :scope + $width = 240px + $item-height = 38px + $padding = 10px + + display none + position fixed + top 0 + 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) + + ul + display block + margin 0 + padding $padding 0 + list-style none + + li + display block + + &.separator + margin-top $padding + padding-top $padding + border-top solid 1px #eee + + &.has-child + > p + cursor default + + > i:last-child + position absolute + top 0 + right 8px + line-height $item-height + + &:hover > ul + visibility visible + + &:active + > p, a + background $theme-color - &:active > p, a - background $theme-color - - > p, a - display block - 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 - width 28px - margin-left -28px - text-align center - - &:hover - > p, a - text-decoration none - background $theme-color - color $theme-color-foreground - - &:active - > p, a - text-decoration none - background darken($theme-color, 10%) - color $theme-color-foreground - - li > ul - visibility hidden - position absolute - top 0 - 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. - - @root.add-event-listener \contextmenu (e) ~> - e.prevent-default! - - @mousedown = (e) ~> - e.prevent-default! - if (!contains @root, e.target) and (@root != e.target) - @close! - return false - - @open = (pos) ~> - all = document.query-selector-all 'body *' - Array.prototype.for-each.call all, (el) ~> - el.add-event-listener \mousedown @mousedown - @root.style.display = \block - @root.style.left = pos.x + \px - @root.style.top = pos.y + \px - - Velocity @root, \finish true - Velocity @root, { opacity: 0 } 0ms - Velocity @root, { - opacity: 1 - } { - queue: false - duration: 100ms - easing: \linear - } - - @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 + display block + 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 + width 28px + margin-left -28px + text-align center + + &:hover + > p, a + text-decoration none + background $theme-color + color $theme-color-foreground + + &:active + > p, a + text-decoration none + background darken($theme-color, 10%) + color $theme-color-foreground + + li > ul + visibility hidden + position absolute + top 0 + 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 + + </style> + <script> + @root.add-event-listener \contextmenu (e) ~> + e.prevent-default! + + @mousedown = (e) ~> + e.prevent-default! + if (!contains @root, e.target) and (@root != e.target) + @close! + return false + + @open = (pos) ~> + all = document.query-selector-all 'body *' + Array.prototype.for-each.call all, (el) ~> + el.add-event-listener \mousedown @mousedown + @root.style.display = \block + @root.style.left = pos.x + \px + @root.style.top = pos.y + \px + + Velocity @root, \finish true + Velocity @root, { opacity: 0 } 0ms + Velocity @root, { + opacity: 1 + } { + queue: false + duration: 100ms + easing: \linear + } + + @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 + </script> +</mk-contextmenu> diff --git a/src/web/app/desktop/tags/crop-window.tag b/src/web/app/desktop/tags/crop-window.tag index 16e1a72b3a2ceca1109fc221412ad122fc26ec02..768c76d952bf616962f610c40f7743966d906c51 100644 --- a/src/web/app/desktop/tags/crop-window.tag +++ b/src/web/app/desktop/tags/crop-window.tag @@ -1,189 +1,188 @@ -mk-crop-window - mk-window@window(is-modal={ true }, width={ '800px' }) - <yield to="header"> - i.fa.fa-crop - | { parent.title } - </yield> - <yield to="content"> - div.body - img@img(src={ parent.image.url + '?thumbnail&quality=80' }, alt='') - div.action - button.skip(onclick={ parent.skip }) クãƒãƒƒãƒ—をスã‚ップ - button.cancel(onclick={ parent.cancel }) ã‚ャンセル - button.ok(onclick={ parent.ok }) 決定 - </yield> - -style. - display block - - > mk-window - [data-yield='header'] - > i - margin-right 4px - - [data-yield='content'] - - > .body - > img - width 100% - max-height 400px - - .cropper-modal { - opacity: 0.8; - } - - .cropper-view-box { - outline-color: $theme-color; - } - - .cropper-line, .cropper-point { - background-color: $theme-color; - } - - .cropper-bg { - animation: cropper-bg 0.5s linear infinite; - } - - @-webkit-keyframes cropper-bg { - 0% { - background-position: 0 0; - } - - 100% { - background-position: -8px -8px; - } - } - - @-moz-keyframes cropper-bg { - 0% { - background-position: 0 0; - } - - 100% { - background-position: -8px -8px; - } - } - - @-ms-keyframes cropper-bg { - 0% { - background-position: 0 0; - } - - 100% { - background-position: -8px -8px; - } - } - - @keyframes cropper-bg { - 0% { - background-position: 0 0; - } - - 100% { - background-position: -8px -8px; - } - } - - > .action - height 72px - background lighten($theme-color, 95%) - - .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 +<mk-crop-window> + <mk-window ref="window" is-modal="{ true }" width="{ '800px' }"><yield to="header"><i class="fa fa-crop"></i>{ parent.title }</yield> +<yield to="content"> + <div class="body"><img ref="img" src="{ parent.image.url + '?thumbnail&quality=80' }" alt=""/></div> + <div class="action"> + <button class="skip" onclick="{ parent.skip }">クãƒãƒƒãƒ—をスã‚ップ</button> + <button class="cancel" onclick="{ parent.cancel }">ã‚ャンセル</button> + <button class="ok" onclick="{ parent.ok }">決定</button> + </div></yield> + </mk-window> + <style type="stylus"> + :scope + display block + + > mk-window + [data-yield='header'] + > i + margin-right 4px + + [data-yield='content'] + + > .body + > img + width 100% + max-height 400px + + .cropper-modal { + opacity: 0.8; + } + + .cropper-view-box { + outline-color: $theme-color; + } + + .cropper-line, .cropper-point { + background-color: $theme-color; + } + + .cropper-bg { + animation: cropper-bg 0.5s linear infinite; + } + + @-webkit-keyframes cropper-bg { + 0% { + background-position: 0 0; + } + + 100% { + background-position: -8px -8px; + } + } + + @-moz-keyframes cropper-bg { + 0% { + background-position: 0 0; + } + + 100% { + background-position: -8px -8px; + } + } + + @-ms-keyframes cropper-bg { + 0% { + background-position: 0 0; + } + + 100% { + background-position: -8px -8px; + } + } + + @keyframes cropper-bg { + 0% { + background-position: 0 0; + } + + 100% { + background-position: -8px -8px; + } + } + + > .action + height 72px + background lighten($theme-color, 95%) + + .ok + .cancel + .skip + display block 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 - - .ok - .cancel - width 120px - - .ok - 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%) - - &: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 - - .cancel - .skip - color #888 - background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) - border solid 1px #e2e2e2 - - &:hover - background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) - border-color #dcdcdc - - &:active - background #ececec - border-color #dcdcdc - - .cancel - right 148px - - .skip - left 16px - width 150px - -script. - @mixin \cropper - - @image = @opts.file - @title = @opts.title - @aspect-ratio = @opts.aspect-ratio - @cropper = null - - @on \mount ~> - @img = @refs.window.refs.img - @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 + 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 + 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 + + .ok + .cancel + width 120px + + .ok + 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%) + + &: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 + + .cancel + .skip + color #888 + background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) + border solid 1px #e2e2e2 + + &:hover + background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) + border-color #dcdcdc + + &:active + background #ececec + border-color #dcdcdc + + .cancel + right 148px + + .skip + left 16px + width 150px + + </style> + <script> + @mixin \cropper + + @image = @opts.file + @title = @opts.title + @aspect-ratio = @opts.aspect-ratio + @cropper = null + + @on \mount ~> + @img = @refs.window.refs.img + @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! - @skip = ~> - @trigger \skiped - @refs.window.close! - - @cancel = ~> - @trigger \canceled - @refs.window.close! + @cancel = ~> + @trigger \canceled + @refs.window.close! + </script> +</mk-crop-window> diff --git a/src/web/app/desktop/tags/debugger.tag b/src/web/app/desktop/tags/debugger.tag index e2b522cb00825894c9fb8fb724165c89a0ce0691..9f9ff2cc4becb6711b52dead1b88ab5934a4fc29 100644 --- a/src/web/app/desktop/tags/debugger.tag +++ b/src/web/app/desktop/tags/debugger.tag @@ -1,87 +1,90 @@ -mk-debugger - mk-window@window(is-modal={ false }, width={ '700px' }, height={ '550px' }) - <yield to="header"> - i.fa.fa-wrench - | Debugger - </yield> - <yield to="content"> - section.progress-dialog - h1 progress-dialog - button.style-normal(onclick={ parent.progress-dialog }): i.fa.fa-play - button.style-normal(onclick={ parent.progress-dialog-destroy }): i.fa.fa-stop - label - p TITLE: - input@progress-title(value='Title') - label - p VAL: - input@progress-value(type='number', oninput={ parent.progress-change }, value=0) - label - p MAX: - input@progress-max(type='number', oninput={ parent.progress-change }, value=100) - </yield> - -style. - > mk-window - [data-yield='header'] - > i - margin-right 4px - - [data-yield='content'] - overflow auto - - > 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 - - > p - display inline - margin 0 - - > .progress-dialog - button - display inline-block - margin 8px - -script. - @mixin \open-window - - @on \mount ~> - @progress-title = @tags['mk-window'].progress-title - @progress-value = @tags['mk-window'].progress-value - @progress-max = @tags['mk-window'].progress-max - - @refs.window.on \closed ~> - @unmount! - - ################################ - - @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-change = ~> - @progress-controller.trigger do - \update - @progress-value.value - @progress-max.value - - @progress-dialog-destroy = ~> - @progress-controller.trigger \close +<mk-debugger> + <mk-window ref="window" is-modal="{ false }" width="{ '700px' }" height="{ '550px' }"><yield to="header"><i class="fa fa-wrench"></i>Debugger</yield> +<yield to="content"> + <section class="progress-dialog"> + <h1>progress-dialog</h1> + <button class="style-normal" onclick="{ parent.progressDialog }"><i class="fa fa-play"></i></button> + <button class="style-normal" onclick="{ parent.progressDialogDestroy }"><i class="fa fa-stop"></i></button> + <label> + <p>TITLE:</p> + <input ref="progressTitle" value="Title"/> + </label> + <label> + <p>VAL:</p> + <input ref="progressValue" type="number" oninput="{ parent.progressChange }" value="0"/> + </label> + <label> + <p>MAX:</p> + <input ref="progressMax" type="number" oninput="{ parent.progressChange }" value="100"/> + </label> + </section></yield> + </mk-window> + <style type="stylus"> + :scope + > mk-window + [data-yield='header'] + > i + margin-right 4px + + [data-yield='content'] + overflow auto + + > 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 + + > p + display inline + margin 0 + + > .progress-dialog + button + display inline-block + margin 8px + + </style> + <script> + @mixin \open-window + + @on \mount ~> + @progress-title = @tags['mk-window'].progress-title + @progress-value = @tags['mk-window'].progress-value + @progress-max = @tags['mk-window'].progress-max + + @refs.window.on \closed ~> + @unmount! + + ################################ + + @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-change = ~> + @progress-controller.trigger do + \update + @progress-value.value + @progress-max.value + + @progress-dialog-destroy = ~> + @progress-controller.trigger \close + </script> +</mk-debugger> diff --git a/src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag b/src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag index f11a0c0857acc22e2e5a882cafb186d679c5ab41..09a746fb9ba2f9b52088955d8bceeaa269fb43a9 100644 --- a/src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag +++ b/src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag @@ -1,56 +1,60 @@ -mk-detect-slow-internet-connection-notice - i: i.fa.fa-exclamation - div: p インターãƒãƒƒãƒˆå›žç·šãŒé…ã„よã†ã§ã™ã€‚ - -style. - display block - 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 +<mk-detect-slow-internet-connection-notice><i><i class="fa fa-exclamation"></i></i> + <div> + <p>インターãƒãƒƒãƒˆå›žç·šãŒé…ã„よã†ã§ã™ã€‚</p> + </div> + <style type="stylus"> + :scope + display block + 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 + > 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 + > div + display block + position absolute + top 0 + left 48px + margin 0 + width 250px + height 48px + color #666 - > p - display block - margin 0 - padding 8px + > p + display block + margin 0 + padding 8px -script. - @mixin \net + </style> + <script> + @mixin \net - @net.on \detected-slow-network ~> - Velocity @root, { - opacity: 1 - } 200ms \linear - set-timeout ~> + @net.on \detected-slow-network ~> Velocity @root, { - opacity: 0 + opacity: 1 } 200ms \linear - , 10000ms + set-timeout ~> + Velocity @root, { + opacity: 0 + } 200ms \linear + , 10000ms + </script> +</mk-detect-slow-internet-connection-notice> diff --git a/src/web/app/desktop/tags/dialog.tag b/src/web/app/desktop/tags/dialog.tag index 88a461db84a4e738ba57dadec7df6ae88f19ab97..d0aab4995c38c86c944a762ce9938b2cb2a0e41b 100644 --- a/src/web/app/desktop/tags/dialog.tag +++ b/src/web/app/desktop/tags/dialog.tag @@ -1,141 +1,147 @@ -mk-dialog - div.bg@bg(onclick={ bg-click }) - div.main@main - header@header - div.body@body - div.buttons - virtual(each={ opts.buttons }) - button(onclick={ _onclick }) { text } - -style. - display block - - > .bg - 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 - - > .main - display block - 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 +<mk-dialog> + <div class="bg" ref="bg" onclick="{ bgClick }"></div> + <div class="main" ref="main"> + <header ref="header"></header> + <div class="body" ref="body"></div> + <div class="buttons"> + <virtual each="{ opts.buttons }"> + <button onclick="{ _onclick }">{ text }</button> + </virtual> + </div> + </div> + <style type="stylus"> + :scope + display block + + > .bg + 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 + + > .main + display block + 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 - - &:active - color darken($theme-color, 10%) - transition color 0s ease - -script. - @can-through = if opts.can-through? then opts.can-through else true - @opts.buttons.for-each (button) ~> - button._onclick = ~> - if button.onclick? - button.onclick! - @close! - - @on \mount ~> - @refs.header.innerHTML = @opts.title - @refs.body.innerHTML = @opts.text - - @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! + // 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 + + &:active + color darken($theme-color, 10%) + transition color 0s ease + + </style> + <script> + @can-through = if opts.can-through? then opts.can-through else true + @opts.buttons.for-each (button) ~> + button._onclick = ~> + if button.onclick? + button.onclick! + @close! + + @on \mount ~> + @refs.header.innerHTML = @opts.title + @refs.body.innerHTML = @opts.text + + @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> diff --git a/src/web/app/desktop/tags/donation.tag b/src/web/app/desktop/tags/donation.tag index 9f8a1a672942bbc08a7699f36362d340e0c8a1ab..49ea8332d3881dec1935abeb1bafb15a86a31391 100644 --- a/src/web/app/desktop/tags/donation.tag +++ b/src/web/app/desktop/tags/donation.tag @@ -1,63 +1,68 @@ -mk-donation - button.close(onclick={ close }) é–‰ã˜ã‚‹ x - div.message - p 利用者ã®çš†ã•ã¾ã€ - p - | 今日ã¯ã€æ—¥æœ¬ã®çš†ã•ã¾ã«ãŠçŸ¥ã‚‰ã›ãŒã‚ã‚Šã¾ã™ã€‚ - | Misskeyã®æ´åŠ©ã‚’ãŠé¡˜ã„ã„ãŸã—ã¾ã™ã€‚ - | ç§ã¯ç‹¬ç«‹æ€§ã‚’守るãŸã‚ã€ä¸€åˆ‡ã®åºƒå‘Šã‚’掲載ã„ãŸã—ã¾ã›ã‚“。 - | å¹³å‡ã§ç´„Â¥1,500ã®å¯„付をã„ãŸã ãã€é‹å–¶ã—ã¦ãŠã‚Šã¾ã™ã€‚ - | æ´åŠ©ã‚’ã—ã¦ãã ã•ã‚‹åˆ©ç”¨è€…ã¯ã»ã‚“ã®å°‘æ•°ã§ã™ã€‚ - | ãŠé¡˜ã„ã„ãŸã—ã¾ã™ã€‚ - | 今日ã€åˆ©ç”¨è€…ã®çš†ã•ã¾ãŒÂ¥300ã”æ´åŠ©ãã ã•ã‚Œã°ã€å‹Ÿé‡‘活動を一時間ã§çµ‚了ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ - | コーヒー1æ¯ã»ã©ã®é‡‘é¡ã§ã™ã€‚ - | Misskeyを活用ã—ã¦ãŠã‚‰ã‚Œã‚‹ã®ã§ã—ãŸã‚‰ã€åºƒå‘Šã‚’掲載ã›ãšã«ã‚‚ã†1年活動ã§ãるよã†ã€ã©ã†ã‹1分ã ã‘ãŠæ™‚é–“ã‚’ãã ã•ã„。 - | ç§ã¯å°ã•ãªéžå–¶åˆ©å€‹äººã§ã™ãŒã€ã‚µãƒ¼ãƒãƒ¼ã€ãƒ—ãƒã‚°ãƒ©ãƒ ã€äººä»¶è²»ãªã©ã€ä¸–ç•Œã§ãƒˆãƒƒãƒ—クラスã®ã‚¦ã‚§ãƒ–サイトåŒç‰ã®ã‚³ã‚¹ãƒˆãŒã‹ã‹ã‚Šã¾ã™ã€‚ - | 利用者ã¯ä½•å„„人ã¨ã„ã¾ã™ãŒã€ä»–ã®å¤§ããªã‚µã‚¤ãƒˆã«æ¯”ã¹ã¦ã»ã‚“ã®å°‘é¡ã®è²»ç”¨ã§é‹å–¶ã—ã¦ã„ã‚‹ã®ã§ã™ã€‚ - | 人間ã®å¯èƒ½æ€§ã€è‡ªç”±ã€ãã—ã¦æ©Ÿä¼šã€‚知è˜ã“ãã€ã“れらã®åŸºç›¤ã‚’æˆã™ã‚‚ã®ã§ã™ã€‚ - | ç§ã¯ã€èª°ã‚‚ãŒç„¡æ–™ã‹ã¤åˆ¶é™ãªã知è˜ã«è§¦ã‚Œã‚‰ã‚Œã‚‹ã¹ãã ã¨ä¿¡ã˜ã¦ã„ã¾ã™ã€‚ - | 募金活動を終了ã—ã€Misskeyã®æ”¹å–„ã«æˆ»ã‚Œã‚‹ã‚ˆã†ã”æ´åŠ©ãã ã•ã„。 - | よã‚ã—ããŠé¡˜ã„ã„ãŸã—ã¾ã™ã€‚ - -style. - display block - color #fff - background #03072C - - > .close - position absolute - top 16px - right 16px - z-index 1 - - > .message - padding 32px - font-size 1.4em - font-family serif - - > p +<mk-donation> + <button class="close" onclick="{ close }">é–‰ã˜ã‚‹ x</button> + <div class="message"> + <p>利用者ã®çš†ã•ã¾ã€</p> + <p> + 今日ã¯ã€æ—¥æœ¬ã®çš†ã•ã¾ã«ãŠçŸ¥ã‚‰ã›ãŒã‚ã‚Šã¾ã™ã€‚ + Misskeyã®æ´åŠ©ã‚’ãŠé¡˜ã„ã„ãŸã—ã¾ã™ã€‚ + ç§ã¯ç‹¬ç«‹æ€§ã‚’守るãŸã‚ã€ä¸€åˆ‡ã®åºƒå‘Šã‚’掲載ã„ãŸã—ã¾ã›ã‚“。 + å¹³å‡ã§ç´„Â¥1,500ã®å¯„付をã„ãŸã ãã€é‹å–¶ã—ã¦ãŠã‚Šã¾ã™ã€‚ + æ´åŠ©ã‚’ã—ã¦ãã ã•ã‚‹åˆ©ç”¨è€…ã¯ã»ã‚“ã®å°‘æ•°ã§ã™ã€‚ + ãŠé¡˜ã„ã„ãŸã—ã¾ã™ã€‚ + 今日ã€åˆ©ç”¨è€…ã®çš†ã•ã¾ãŒÂ¥300ã”æ´åŠ©ãã ã•ã‚Œã°ã€å‹Ÿé‡‘活動を一時間ã§çµ‚了ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ + コーヒー1æ¯ã»ã©ã®é‡‘é¡ã§ã™ã€‚ + Misskeyを活用ã—ã¦ãŠã‚‰ã‚Œã‚‹ã®ã§ã—ãŸã‚‰ã€åºƒå‘Šã‚’掲載ã›ãšã«ã‚‚ã†1年活動ã§ãるよã†ã€ã©ã†ã‹1分ã ã‘ãŠæ™‚é–“ã‚’ãã ã•ã„。 + ç§ã¯å°ã•ãªéžå–¶åˆ©å€‹äººã§ã™ãŒã€ã‚µãƒ¼ãƒãƒ¼ã€ãƒ—ãƒã‚°ãƒ©ãƒ ã€äººä»¶è²»ãªã©ã€ä¸–ç•Œã§ãƒˆãƒƒãƒ—クラスã®ã‚¦ã‚§ãƒ–サイトåŒç‰ã®ã‚³ã‚¹ãƒˆãŒã‹ã‹ã‚Šã¾ã™ã€‚ + 利用者ã¯ä½•å„„人ã¨ã„ã¾ã™ãŒã€ä»–ã®å¤§ããªã‚µã‚¤ãƒˆã«æ¯”ã¹ã¦ã»ã‚“ã®å°‘é¡ã®è²»ç”¨ã§é‹å–¶ã—ã¦ã„ã‚‹ã®ã§ã™ã€‚ + 人間ã®å¯èƒ½æ€§ã€è‡ªç”±ã€ãã—ã¦æ©Ÿä¼šã€‚知è˜ã“ãã€ã“れらã®åŸºç›¤ã‚’æˆã™ã‚‚ã®ã§ã™ã€‚ + ç§ã¯ã€èª°ã‚‚ãŒç„¡æ–™ã‹ã¤åˆ¶é™ãªã知è˜ã«è§¦ã‚Œã‚‰ã‚Œã‚‹ã¹ãã ã¨ä¿¡ã˜ã¦ã„ã¾ã™ã€‚ + 募金活動を終了ã—ã€Misskeyã®æ”¹å–„ã«æˆ»ã‚Œã‚‹ã‚ˆã†ã”æ´åŠ©ãã ã•ã„。 + よã‚ã—ããŠé¡˜ã„ã„ãŸã—ã¾ã™ã€‚ + </p> + </div> + <style type="stylus"> + :scope display block - margin 0 auto - max-width 1200px + color #fff + background #03072C - > p:first-child - margin-bottom 16px + > .close + position absolute + top 16px + right 16px + z-index 1 -script. - @mixin \api - @mixin \i + > .message + padding 32px + font-size 1.4em + font-family serif - @close = (e) ~> - e.prevent-default! - e.stop-propagation! + > p + display block + margin 0 auto + max-width 1200px - @I.data.no_donation = true - @api \i/appdata/set do - data: JSON.stringify do - no_donation: @I.data.no_donation - .then ~> - @update-i! + > p:first-child + margin-bottom 16px - @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> diff --git a/src/web/app/desktop/tags/drive/base-contextmenu.tag b/src/web/app/desktop/tags/drive/base-contextmenu.tag index c8b51009ea57227a1d57c5d2353de1253b349468..d3a85e91579e1abba9f455a861f9ba827c21f83c 100644 --- a/src/web/app/desktop/tags/drive/base-contextmenu.tag +++ b/src/web/app/desktop/tags/drive/base-contextmenu.tag @@ -1,28 +1,31 @@ -mk-drive-browser-base-contextmenu - mk-contextmenu@ctx - ul - li(onclick={ parent.create-folder }): p - i.fa.fa-folder-o - | ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’ä½œæˆ - li(onclick={ parent.upload }): p - i.fa.fa-upload - | ファイルをアップãƒãƒ¼ãƒ‰ +<mk-drive-browser-base-contextmenu> + <mk-contextmenu ref="ctx"> + <ul> + <li onclick="{ parent.createFolder }"> + <p><i class="fa fa-folder-o"></i>フォルダーを作æˆ</p> + </li> + <li onclick="{ parent.upload }"> + <p><i class="fa fa-upload"></i>ファイルをアップãƒãƒ¼ãƒ‰</p> + </li> + </ul> + </mk-contextmenu> + <script> + @browser = @opts.browser -script. - @browser = @opts.browser + @on \mount ~> + @refs.ctx.on \closed ~> + @trigger \closed + @unmount! - @on \mount ~> - @refs.ctx.on \closed ~> - @trigger \closed - @unmount! + @open = (pos) ~> + @refs.ctx.open pos - @open = (pos) ~> - @refs.ctx.open pos + @create-folder = ~> + @browser.create-folder! + @refs.ctx.close! - @create-folder = ~> - @browser.create-folder! - @refs.ctx.close! - - @upload = ~> - @browser.select-local-file! - @refs.ctx.close! + @upload = ~> + @browser.select-local-file! + @refs.ctx.close! + </script> +</mk-drive-browser-base-contextmenu> diff --git a/src/web/app/desktop/tags/drive/browser-window.tag b/src/web/app/desktop/tags/drive/browser-window.tag index b3a5fc9a4724b8fc2ecd788dc441c1fa74733f69..c7447a3c2144e530008b06622f0bcb5410b7c013 100644 --- a/src/web/app/desktop/tags/drive/browser-window.tag +++ b/src/web/app/desktop/tags/drive/browser-window.tag @@ -1,29 +1,28 @@ -mk-drive-browser-window - mk-window@window(is-modal={ false }, width={ '800px' }, height={ '500px' }) - <yield to="header"> - i.fa.fa-cloud - | ドライブ - </yield> - <yield to="content"> - mk-drive-browser(multiple={ true }, folder={ parent.folder }) - </yield> +<mk-drive-browser-window> + <mk-window ref="window" is-modal="{ false }" width="{ '800px' }" height="{ '500px' }"><yield to="header"><i class="fa fa-cloud"></i>ドライブ</yield> +<yield to="content"> + <mk-drive-browser multiple="{ true }" folder="{ parent.folder }"></mk-drive-browser></yield> + </mk-window> + <style type="stylus"> + :scope + > mk-window + [data-yield='header'] + > i + margin-right 4px -style. - > mk-window - [data-yield='header'] - > i - margin-right 4px + [data-yield='content'] + > mk-drive-browser + height 100% - [data-yield='content'] - > mk-drive-browser - height 100% + </style> + <script> + @folder = if @opts.folder? then @opts.folder else null -script. - @folder = if @opts.folder? then @opts.folder else null + @on \mount ~> + @refs.window.on \closed ~> + @unmount! - @on \mount ~> - @refs.window.on \closed ~> - @unmount! - - @close = ~> - @refs.window.close! + @close = ~> + @refs.window.close! + </script> +</mk-drive-browser-window> diff --git a/src/web/app/desktop/tags/drive/browser.tag b/src/web/app/desktop/tags/drive/browser.tag index 62e6425fe590987f82fd1e6aa6546912f4e61886..2bcb15f8736e8e1174ec1be87cd9562f167ae893 100644 --- a/src/web/app/desktop/tags/drive/browser.tag +++ b/src/web/app/desktop/tags/drive/browser.tag @@ -1,634 +1,637 @@ -mk-drive-browser - nav - div.path(oncontextmenu={ path-oncontextmenu }) - mk-drive-browser-nav-folder(class={ current: folder == null }, folder={ null }) - virtual(each={ folder in hierarchy-folders }) - span.separator: i.fa.fa-angle-right - mk-drive-browser-nav-folder(folder={ folder }) - span.separator(if={ folder != null }): i.fa.fa-angle-right - span.folder.current(if={ folder != null }) - | { folder.name } - input.search(type='search', placeholder!=' 検索') - div.main@main(class={ uploading: uploads.length > 0, loading: loading }, onmousedown={ onmousedown }, ondragover={ ondragover }, ondragenter={ ondragenter }, ondragleave={ ondragleave }, ondrop={ ondrop }, oncontextmenu={ oncontextmenu }) - div.selection@selection - div.contents@contents - div.folders@folders-container(if={ folders.length > 0 }) - virtual(each={ folder in folders }) - mk-drive-browser-folder.folder(folder={ folder }) - button(if={ more-folders }) - | ã‚‚ã£ã¨èªã¿è¾¼ã‚€ - div.files@files-container(if={ files.length > 0 }) - virtual(each={ file in files }) - mk-drive-browser-file.file(file={ file }) - button(if={ more-files }) - | ã‚‚ã£ã¨èªã¿è¾¼ã‚€ - div.empty(if={ files.length == 0 && folders.length == 0 && !loading }) - p(if={ draghover }) - | ドãƒãƒƒãƒ—ã§ã™ã‹ï¼Ÿã„ã„ã§ã™ã‚ˆã€ãƒœã‚¯ã¯ã‚«ãƒ¯ã‚¤ã‚¤ã§ã™ã‹ã‚‰ã - p(if={ !draghover && folder == null }) - strong ドライブã«ã¯ä½•ã‚‚ã‚ã‚Šã¾ã›ã‚“。 - br - | å³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€Œãƒ•ã‚¡ã‚¤ãƒ«ã‚’アップãƒãƒ¼ãƒ‰ã€ã‚’é¸ã‚“ã ã‚Šã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグ&ドãƒãƒƒãƒ—ã™ã‚‹ã“ã¨ã§ã‚‚アップãƒãƒ¼ãƒ‰ã§ãã¾ã™ã€‚ - p(if={ !draghover && folder != null }) - | ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã¯ç©ºã§ã™ - div.loading(if={ loading }). +<mk-drive-browser> + <nav> + <div class="path" oncontextmenu="{ pathOncontextmenu }"> + <mk-drive-browser-nav-folder class="{ current: folder == null }" folder="{ null }"></mk-drive-browser-nav-folder> + <virtual each="{ folder in hierarchyFolders }"><span class="separator"><i class="fa fa-angle-right"></i></span> + <mk-drive-browser-nav-folder folder="{ folder }"></mk-drive-browser-nav-folder> + </virtual><span class="separator" if="{ folder != null }"><i class="fa fa-angle-right"></i></span><span class="folder current" if="{ folder != null }">{ folder.name }</span> + </div> + <input class="search" type="search" placeholder=" 検索"/> + </nav> + <div class="main { uploading: uploads.length > 0, loading: loading }" ref="main" onmousedown="{ onmousedown }" ondragover="{ ondragover }" ondragenter="{ ondragenter }" ondragleave="{ ondragleave }" ondrop="{ ondrop }" oncontextmenu="{ oncontextmenu }"> + <div class="selection" ref="selection"></div> + <div class="contents" ref="contents"> + <div class="folders" ref="foldersContainer" if="{ folders.length > 0 }"> + <virtual each="{ folder in folders }"> + <mk-drive-browser-folder class="folder" folder="{ folder }"></mk-drive-browser-folder> + </virtual> + <button if="{ moreFolders }">ã‚‚ã£ã¨èªã¿è¾¼ã‚€</button> + </div> + <div class="files" ref="filesContainer" if="{ files.length > 0 }"> + <virtual each="{ file in files }"> + <mk-drive-browser-file class="file" file="{ file }"></mk-drive-browser-file> + </virtual> + <button if="{ moreFiles }">ã‚‚ã£ã¨èªã¿è¾¼ã‚€</button> + </div> + <div class="empty" if="{ files.length == 0 && folders.length == 0 && !loading }"> + <p if="{ draghover }">ドãƒãƒƒãƒ—ã§ã™ã‹ï¼Ÿã„ã„ã§ã™ã‚ˆã€ãƒœã‚¯ã¯ã‚«ãƒ¯ã‚¤ã‚¤ã§ã™ã‹ã‚‰ã</p> + <p if="{ !draghover && folder == null }"><strong>ドライブã«ã¯ä½•ã‚‚ã‚ã‚Šã¾ã›ã‚“。</strong><br/>å³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€Œãƒ•ã‚¡ã‚¤ãƒ«ã‚’アップãƒãƒ¼ãƒ‰ã€ã‚’é¸ã‚“ã ã‚Šã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグ&ドãƒãƒƒãƒ—ã™ã‚‹ã“ã¨ã§ã‚‚アップãƒãƒ¼ãƒ‰ã§ãã¾ã™ã€‚</p> + <p if="{ !draghover && folder != null }">ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã¯ç©ºã§ã™</p> + </div> + </div> + <div class="loading" if="{ loading }"> <div class="spinner"> <div class="dot1"></div> <div class="dot2"></div> </div> - div.dropzone(if={ draghover }) - mk-uploader@uploader - input@file-input(type='file', accept='*/*', multiple, tabindex='-1', onchange={ change-file-input }) - -style. - display block - - > nav - display block - z-index 2 - width 100% - overflow auto - font-size 0.9em - color #555 - background #fff - //border-bottom 1px solid #dfdfdf - box-shadow 0 1px 0 rgba(0, 0, 0, 0.05) - - &, * - user-select none - - > .path - display inline-block - vertical-align bottom - margin 0 - padding 0 8px - width calc(100% - 200px) - line-height 38px - white-space nowrap - - > * - display inline-block - margin 0 - padding 0 8px - line-height 38px - cursor pointer - - i - margin-right 4px - - * - pointer-events none - - &:hover - text-decoration underline - - &.current - font-weight bold - cursor default + </div> + </div> + <div class="dropzone" if="{ draghover }"></div> + <mk-uploader ref="uploader"></mk-uploader> + <input ref="fileInput" type="file" accept="*/*" multiple="multiple" tabindex="-1" onchange="{ changeFileInput }"/> + <style type="stylus"> + :scope + display block + + > nav + display block + z-index 2 + width 100% + overflow auto + font-size 0.9em + color #555 + background #fff + //border-bottom 1px solid #dfdfdf + box-shadow 0 1px 0 rgba(0, 0, 0, 0.05) - &:hover - text-decoration none + &, * + user-select none - &.separator + > .path + display inline-block + vertical-align bottom margin 0 - padding 0 - opacity 0.5 - cursor default + padding 0 8px + width calc(100% - 200px) + line-height 38px + white-space nowrap - > i + > * + display inline-block margin 0 + padding 0 8px + line-height 38px + cursor pointer - > .search - display inline-block - vertical-align bottom - user-select text - cursor auto - margin 0 - padding 0 18px - width 200px - font-size 1em - line-height 38px - background transparent - outline none - //border solid 1px #ddd - border none - border-radius 0 - box-shadow none - transition color 0.5s ease, border 0.5s ease - font-family FontAwesome, sans-serif - - &[data-active='true'] - background #fff + i + margin-right 4px + + * + pointer-events none - &::-webkit-input-placeholder, - &:-ms-input-placeholder, - &:-moz-placeholder - color $ui-controll-foreground-color + &:hover + text-decoration underline - > .main - padding 8px - height calc(100% - 38px) - overflow auto + &.current + font-weight bold + cursor default - &, * - user-select none + &:hover + text-decoration none - &.loading - cursor wait !important + &.separator + margin 0 + padding 0 + opacity 0.5 + cursor default - * + > i + margin 0 + + > .search + display inline-block + vertical-align bottom + user-select text + cursor auto + margin 0 + padding 0 18px + width 200px + font-size 1em + line-height 38px + background transparent + outline none + //border solid 1px #ddd + border none + border-radius 0 + box-shadow none + transition color 0.5s ease, border 0.5s ease + font-family FontAwesome, sans-serif + + &[data-active='true'] + background #fff + + &::-webkit-input-placeholder, + &:-ms-input-placeholder, + &:-moz-placeholder + color $ui-controll-foreground-color + + > .main + padding 8px + height calc(100% - 38px) + overflow auto + + &, * + user-select none + + &.loading + cursor wait !important + + * + pointer-events none + + > .contents + opacity 0.5 + + &.uploading + height calc(100% - 38px - 100px) + + > .selection + display none + position absolute + z-index 128 + top 0 + left 0 + border solid 1px $theme-color + background rgba($theme-color, 0.5) + pointer-events none + + > .contents + + > .folders + &:after + content "" + display block + clear both + + > .folder + float left + + > .files + &:after + content "" + display block + clear both + + > .file + float left + + > .empty + padding 16px + text-align center + color #999 + pointer-events none + + > p + margin 0 + + > .loading + .spinner + margin 100px auto + width 40px + height 40px + text-align center + + animation sk-rotate 2.0s infinite linear + + .dot1, .dot2 + width 60% + height 60% + display inline-block + position absolute + top 0 + background-color rgba(0, 0, 0, 0.3) + border-radius 100% + + animation sk-bounce 2.0s infinite ease-in-out + + .dot2 + top auto + bottom 0 + animation-delay -1.0s + + @keyframes sk-rotate { 100% { transform: rotate(360deg); }} + + @keyframes sk-bounce { + 0%, 100% { + transform: scale(0.0); + } 50% { + transform: scale(1.0); + } + } + + > .dropzone + position absolute + left 0 + top 38px + width 100% + height calc(100% - 38px) + border dashed 2px rgba($theme-color, 0.5) pointer-events none - > .contents - opacity 0.5 + > mk-uploader + height 100px + padding 16px + background #fff - &.uploading - height calc(100% - 38px - 100px) + > input + display none - > .selection - display none - position absolute - z-index 128 - top 0 - left 0 - border solid 1px $theme-color - background rgba($theme-color, 0.5) - pointer-events none + </style> + <script> + @mixin \api + @mixin \dialog + @mixin \input-dialog + @mixin \stream - > .contents + @files = [] + @folders = [] + @hierarchy-folders = [] - > .folders - &:after - content "" - display block - clear both + @uploads = [] - > .folder - float left + # ç¾åœ¨ã®éšŽå±¤(フォルダ) + # * null ã§ãƒ«ãƒ¼ãƒˆã‚’表㙠+ @folder = null - > .files - &:after - content "" - display block - clear both + @multiple = if @opts.multiple? then @opts.multiple else false - > .file - float left + # ドãƒãƒƒãƒ—ã•ã‚Œã‚ˆã†ã¨ã—ã¦ã„ã‚‹ã‹ + @draghover = false - > .empty - padding 16px - text-align center - color #999 - pointer-events none + # 自信ã®æ‰€æœ‰ã™ã‚‹ã‚¢ã‚¤ãƒ†ãƒ ãŒãƒ‰ãƒ©ãƒƒã‚°ã‚’スタートã•ã›ãŸã‹ + # (自分自身ã®éšŽå±¤ã«ãƒ‰ãƒãƒƒãƒ—ã§ããªã„よã†ã«ã™ã‚‹ãŸã‚ã®ãƒ•ãƒ©ã‚°) + @is-drag-source = false - > p - margin 0 + @on \mount ~> + @refs.uploader.on \uploaded (file) ~> + @add-file file, true - > .loading - .spinner - margin 100px auto - width 40px - height 40px - text-align center + @refs.uploader.on \change-uploads (uploads) ~> + @uploads = uploads + @update! - animation sk-rotate 2.0s infinite linear + @stream.on \drive_file_created @on-stream-drive-file-created + @stream.on \drive_file_updated @on-stream-drive-file-updated + @stream.on \drive_folder_created @on-stream-drive-folder-created + @stream.on \drive_folder_updated @on-stream-drive-folder-updated - .dot1, .dot2 - width 60% - height 60% - display inline-block - position absolute - top 0 - background-color rgba(0, 0, 0, 0.3) - border-radius 100% - - animation sk-bounce 2.0s infinite ease-in-out - - .dot2 - top auto - bottom 0 - animation-delay -1.0s - - @keyframes sk-rotate { 100% { transform: rotate(360deg); }} - - @keyframes sk-bounce { - 0%, 100% { - transform: scale(0.0); - } 50% { - transform: scale(1.0); - } - } - - > .dropzone - position absolute - left 0 - top 38px - width 100% - height calc(100% - 38px) - border dashed 2px rgba($theme-color, 0.5) - pointer-events none - - > mk-uploader - height 100px - padding 16px - background #fff - - > input - display none - -script. - @mixin \api - @mixin \dialog - @mixin \input-dialog - @mixin \stream - - @files = [] - @folders = [] - @hierarchy-folders = [] - - @uploads = [] - - # ç¾åœ¨ã®éšŽå±¤(フォルダ) - # * null ã§ãƒ«ãƒ¼ãƒˆã‚’表㙠- @folder = null - - @multiple = if @opts.multiple? then @opts.multiple else false - - # ドãƒãƒƒãƒ—ã•ã‚Œã‚ˆã†ã¨ã—ã¦ã„ã‚‹ã‹ - @draghover = false - - # 自信ã®æ‰€æœ‰ã™ã‚‹ã‚¢ã‚¤ãƒ†ãƒ ãŒãƒ‰ãƒ©ãƒƒã‚°ã‚’スタートã•ã›ãŸã‹ - # (自分自身ã®éšŽå±¤ã«ãƒ‰ãƒãƒƒãƒ—ã§ããªã„よã†ã«ã™ã‚‹ãŸã‚ã®ãƒ•ãƒ©ã‚°) - @is-drag-source = false - - @on \mount ~> - @refs.uploader.on \uploaded (file) ~> - @add-file file, true + # Riotã®ãƒã‚°ã§nullを渡ã—ã¦ã‚‚""ã«ãªã‚‹ + # https://github.com/riot/riot/issues/2080 + #if @opts.folder? + if @opts.folder? and @opts.folder != '' + @move @opts.folder + else + @load! - @refs.uploader.on \change-uploads (uploads) ~> - @uploads = uploads - @update! + @on \unmount ~> + @stream.off \drive_file_created @on-stream-drive-file-created + @stream.off \drive_file_updated @on-stream-drive-file-updated + @stream.off \drive_folder_created @on-stream-drive-folder-created + @stream.off \drive_folder_updated @on-stream-drive-folder-updated - @stream.on \drive_file_created @on-stream-drive-file-created - @stream.on \drive_file_updated @on-stream-drive-file-updated - @stream.on \drive_folder_created @on-stream-drive-folder-created - @stream.on \drive_folder_updated @on-stream-drive-folder-updated - - # Riotã®ãƒã‚°ã§nullを渡ã—ã¦ã‚‚""ã«ãªã‚‹ - # https://github.com/riot/riot/issues/2080 - #if @opts.folder? - if @opts.folder? and @opts.folder != '' - @move @opts.folder - else - @load! - - @on \unmount ~> - @stream.off \drive_file_created @on-stream-drive-file-created - @stream.off \drive_file_updated @on-stream-drive-file-updated - @stream.off \drive_folder_created @on-stream-drive-folder-created - @stream.off \drive_folder_updated @on-stream-drive-folder-updated - - @on-stream-drive-file-created = (file) ~> - @add-file file, true - - @on-stream-drive-file-updated = (file) ~> - current = if @folder? then @folder.id else null - if current != file.folder_id - @remove-file file - else + @on-stream-drive-file-created = (file) ~> @add-file file, true - @on-stream-drive-folder-created = (folder) ~> - @add-folder folder, true + @on-stream-drive-file-updated = (file) ~> + current = if @folder? then @folder.id else null + if current != file.folder_id + @remove-file file + else + @add-file file, true - @on-stream-drive-folder-updated = (folder) ~> - current = if @folder? then @folder.id else null - if current != folder.parent_id - @remove-folder folder - else + @on-stream-drive-folder-created = (folder) ~> @add-folder folder, true - @onmousedown = (e) ~> - if (contains @refs.folders-container, e.target) or (contains @refs.files-container, e.target) - return true + @on-stream-drive-folder-updated = (folder) ~> + current = if @folder? then @folder.id else null + if current != folder.parent_id + @remove-folder folder + else + @add-folder folder, true - rect = @refs.main.get-bounding-client-rect! + @onmousedown = (e) ~> + if (contains @refs.folders-container, e.target) or (contains @refs.files-container, e.target) + return true - left = e.page-x + @refs.main.scroll-left - rect.left - window.page-x-offset - top = e.page-y + @refs.main.scroll-top - rect.top - window.page-y-offset + rect = @refs.main.get-bounding-client-rect! - move = (e) ~> - @refs.selection.style.display = \block + left = e.page-x + @refs.main.scroll-left - rect.left - window.page-x-offset + top = e.page-y + @refs.main.scroll-top - rect.top - window.page-y-offset - cursor-x = e.page-x + @refs.main.scroll-left - rect.left - window.page-x-offset - cursor-y = e.page-y + @refs.main.scroll-top - rect.top - window.page-y-offset - w = cursor-x - left - h = cursor-y - top + move = (e) ~> + @refs.selection.style.display = \block - if w > 0 - @refs.selection.style.width = w + \px - @refs.selection.style.left = left + \px - else - @refs.selection.style.width = -w + \px - @refs.selection.style.left = cursor-x + \px + cursor-x = e.page-x + @refs.main.scroll-left - rect.left - window.page-x-offset + cursor-y = e.page-y + @refs.main.scroll-top - rect.top - window.page-y-offset + w = cursor-x - left + h = cursor-y - top - if h > 0 - @refs.selection.style.height = h + \px - @refs.selection.style.top = top + \px - else - @refs.selection.style.height = -h + \px - @refs.selection.style.top = cursor-y + \px + if w > 0 + @refs.selection.style.width = w + \px + @refs.selection.style.left = left + \px + else + @refs.selection.style.width = -w + \px + @refs.selection.style.left = cursor-x + \px - up = (e) ~> - document.document-element.remove-event-listener \mousemove move - document.document-element.remove-event-listener \mouseup up + if h > 0 + @refs.selection.style.height = h + \px + @refs.selection.style.top = top + \px + else + @refs.selection.style.height = -h + \px + @refs.selection.style.top = cursor-y + \px - @refs.selection.style.display = \none + up = (e) ~> + document.document-element.remove-event-listener \mousemove move + document.document-element.remove-event-listener \mouseup up - document.document-element.add-event-listener \mousemove move - document.document-element.add-event-listener \mouseup up + @refs.selection.style.display = \none - @path-oncontextmenu = (e) ~> - e.prevent-default! - e.stop-immediate-propagation! - return false + document.document-element.add-event-listener \mousemove move + document.document-element.add-event-listener \mouseup up - @ondragover = (e) ~> - e.prevent-default! - e.stop-propagation! + @path-oncontextmenu = (e) ~> + e.prevent-default! + e.stop-immediate-propagation! + return false - # ドラッグ元ãŒè‡ªåˆ†è‡ªèº«ã®æ‰€æœ‰ã™ã‚‹ã‚¢ã‚¤ãƒ†ãƒ ã‹ã©ã†ã‹ - if !@is-drag-source - # ドラッグã•ã‚Œã¦ããŸã‚‚ã®ãŒãƒ•ã‚¡ã‚¤ãƒ«ã ã£ãŸã‚‰ - if e.data-transfer.effect-allowed == \all - e.data-transfer.drop-effect = \copy + @ondragover = (e) ~> + e.prevent-default! + e.stop-propagation! + + # ドラッグ元ãŒè‡ªåˆ†è‡ªèº«ã®æ‰€æœ‰ã™ã‚‹ã‚¢ã‚¤ãƒ†ãƒ ã‹ã©ã†ã‹ + if !@is-drag-source + # ドラッグã•ã‚Œã¦ããŸã‚‚ã®ãŒãƒ•ã‚¡ã‚¤ãƒ«ã ã£ãŸã‚‰ + if e.data-transfer.effect-allowed == \all + e.data-transfer.drop-effect = \copy + else + e.data-transfer.drop-effect = \move + @draghover = true else - e.data-transfer.drop-effect = \move - @draghover = true - else - # 自分自身ã«ã¯ãƒ‰ãƒãƒƒãƒ—ã•ã›ãªã„ - e.data-transfer.drop-effect = \none - return false - - @ondragenter = (e) ~> - e.prevent-default! - if !@is-drag-source - @draghover = true - - @ondragleave = (e) ~> - @draghover = false + # 自分自身ã«ã¯ãƒ‰ãƒãƒƒãƒ—ã•ã›ãªã„ + e.data-transfer.drop-effect = \none + return false - @ondrop = (e) ~> - e.prevent-default! - e.stop-propagation! + @ondragenter = (e) ~> + e.prevent-default! + if !@is-drag-source + @draghover = true - @draghover = false + @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, @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 + if (@files.some (f) ~> f.id == file) + return false + @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 + if (@folders.some (f) ~> f.id == folder) + return false + @remove-folder folder + @api \drive/folders/update do + folder_id: folder + parent_id: if @folder? then @folder.id else \null + .then ~> + # something + .catch (err) ~> + if err == 'detected-circular-definition' + @dialog do + '<i class="fa fa-exclamation-triangle"></i>æ“作を完了ã§ãã¾ã›ã‚“' + '移動先ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã¯ã€ç§»å‹•ã™ã‚‹ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã®ã‚µãƒ–フォルダーã§ã™ã€‚' + [ + text: \OK + ] - # ドãƒãƒƒãƒ—ã•ã‚Œã¦ããŸã‚‚ã®ãŒãƒ•ã‚¡ã‚¤ãƒ«ã ã£ãŸã‚‰ - if e.data-transfer.files.length > 0 - Array.prototype.for-each.call e.data-transfer.files, (file) ~> - @upload file, @folder return false - # データå–å¾— - data = e.data-transfer.get-data 'text' - if !data? + @oncontextmenu = (e) ~> + e.prevent-default! + e.stop-immediate-propagation! + + ctx = document.body.append-child document.create-element \mk-drive-browser-base-contextmenu + ctx = riot.mount ctx, do + browser: @ + ctx = ctx.0 + ctx.open do + x: e.page-x - window.page-x-offset + y: e.page-y - window.page-y-offset + return false - # パース - obj = JSON.parse data + @select-local-file = ~> + @refs.file-input.click! - # (ドライブã®)ファイルã ã£ãŸã‚‰ - if obj.type == \file - file = obj.id - if (@files.some (f) ~> f.id == file) - return false - @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 + @create-folder = ~> + name <~ @input-dialog do + 'フォルダー作æˆ' + 'フォルダーå' + null - # (ドライブã®)フォルダーã ã£ãŸã‚‰ - else if obj.type == \folder - folder = obj.id - # 移動先ãŒè‡ªåˆ†è‡ªèº«ãªã‚‰reject - if @folder? and folder == @folder.id - return false - if (@folders.some (f) ~> f.id == folder) - return false - @remove-folder folder - @api \drive/folders/update do - folder_id: folder - parent_id: if @folder? then @folder.id else \null - .then ~> - # something + @api \drive/folders/create do + name: name + folder_id: if @folder? then @folder.id else undefined + .then (folder) ~> + @add-folder folder, true + @update! .catch (err) ~> - if err == 'detected-circular-definition' - @dialog do - '<i class="fa fa-exclamation-triangle"></i>æ“作を完了ã§ãã¾ã›ã‚“' - '移動先ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã¯ã€ç§»å‹•ã™ã‚‹ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã®ã‚µãƒ–フォルダーã§ã™ã€‚' - [ - text: \OK - ] - - return false - - @oncontextmenu = (e) ~> - e.prevent-default! - e.stop-immediate-propagation! - - ctx = document.body.append-child document.create-element \mk-drive-browser-base-contextmenu - ctx = riot.mount ctx, do - browser: @ - ctx = ctx.0 - ctx.open do - x: e.page-x - window.page-x-offset - y: e.page-y - window.page-y-offset - - return false - - @select-local-file = ~> - @refs.file-input.click! - - @create-folder = ~> - name <~ @input-dialog do - 'フォルダー作æˆ' - 'フォルダーå' - null - - @api \drive/folders/create do - name: name - folder_id: if @folder? then @folder.id else undefined - .then (folder) ~> - @add-folder folder, true - @update! - .catch (err) ~> - console.error err + console.error err - @change-file-input = ~> - files = @refs.file-input.files - for i from 0 to files.length - 1 - file = files.item i - @upload file, @folder + @change-file-input = ~> + files = @refs.file-input.files + for i from 0 to files.length - 1 + file = files.item i + @upload file, @folder - @upload = (file, folder) ~> - if folder? and typeof folder == \object - folder = folder.id - @refs.uploader.upload file, folder + @upload = (file, folder) ~> + if folder? and typeof folder == \object + folder = folder.id + @refs.uploader.upload file, folder - @get-selection = ~> - @files.filter (file) -> file._selected + @get-selection = ~> + @files.filter (file) -> file._selected - @new-window = (folder-id) ~> - browser = document.body.append-child document.create-element \mk-drive-browser-window - riot.mount browser, do - folder: folder-id + @new-window = (folder-id) ~> + browser = document.body.append-child document.create-element \mk-drive-browser-window + riot.mount browser, do + folder: folder-id - @move = (target-folder) ~> - if target-folder? and typeof target-folder == \object - target-folder = target-folder.id + @move = (target-folder) ~> + if target-folder? and typeof target-folder == \object + target-folder = target-folder.id - if target-folder == null - @go-root! - return + if target-folder == null + @go-root! + return - @loading = true - @update! + @loading = true + @update! - @api \drive/folders/show do - folder_id: target-folder - .then (folder) ~> - @folder = folder - @hierarchy-folders = [] + @api \drive/folders/show do + folder_id: target-folder + .then (folder) ~> + @folder = folder + @hierarchy-folders = [] - x = (f) ~> - @hierarchy-folders.unshift f - if f.parent? - x f.parent + x = (f) ~> + @hierarchy-folders.unshift f + if f.parent? + x f.parent - if folder.parent? - x folder.parent + if folder.parent? + x folder.parent + + @update! + @load! + .catch (err, text-status) -> + console.error err + + @add-folder = (folder, unshift = false) ~> + current = if @folder? then @folder.id else null + if current != folder.parent_id + return + + if (@folders.some (f) ~> f.id == folder.id) + exist = (@folders.map (f) -> f.id).index-of folder.id + @folders[exist] = folder + @update! + return + + if unshift + @folders.unshift folder + else + @folders.push folder @update! - @load! - .catch (err, text-status) -> - console.error err - - @add-folder = (folder, unshift = false) ~> - current = if @folder? then @folder.id else null - if current != folder.parent_id - return - - if (@folders.some (f) ~> f.id == folder.id) - exist = (@folders.map (f) -> f.id).index-of folder.id - @folders[exist] = folder - @update! - return - if unshift - @folders.unshift folder - else - @folders.push folder + @add-file = (file, unshift = false) ~> + current = if @folder? then @folder.id else null + if current != file.folder_id + return + + if (@files.some (f) ~> f.id == file.id) + exist = (@files.map (f) -> f.id).index-of file.id + @files[exist] = file + @update! + return - @update! + if unshift + @files.unshift file + else + @files.push file - @add-file = (file, unshift = false) ~> - current = if @folder? then @folder.id else null - if current != file.folder_id - return + @update! - if (@files.some (f) ~> f.id == file.id) - exist = (@files.map (f) -> f.id).index-of file.id - @files[exist] = file + @remove-folder = (folder) ~> + if typeof folder == \object + folder = folder.id + @folders = @folders.filter (f) -> f.id != folder @update! - return - - if unshift - @files.unshift file - else - @files.push file - - @update! - - @remove-folder = (folder) ~> - if typeof folder == \object - folder = folder.id - @folders = @folders.filter (f) -> f.id != folder - @update! - - @remove-file = (file) ~> - if typeof file == \object - file = file.id - @files = @files.filter (f) -> f.id != file - @update! - - @go-root = ~> - if @folder != null - @folder = null - @hierarchy-folders = [] + + @remove-file = (file) ~> + if typeof file == \object + file = file.id + @files = @files.filter (f) -> f.id != file @update! - @load! - @load = ~> - @folders = [] - @files = [] - @more-folders = false - @more-files = false - @loading = true - @update! - - load-folders = null - load-files = null - - folders-max = 30 - files-max = 30 - - # フォルダ一覧å–å¾— - @api \drive/folders do - folder_id: if @folder? then @folder.id else null - limit: folders-max + 1 - .then (folders) ~> - if folders.length == folders-max + 1 - @more-folders = true - folders.pop! - load-folders := folders - complete! - .catch (err, text-status) ~> - console.error err - - # ファイル一覧å–å¾— - @api \drive/files do - folder_id: if @folder? then @folder.id else null - limit: files-max + 1 - .then (files) ~> - if files.length == files-max + 1 - @more-files = true - files.pop! - load-files := files - complete! - .catch (err, text-status) ~> - console.error err - - flag = false - complete = ~> - if flag - load-folders.for-each (folder) ~> - @add-folder folder - load-files.for-each (file) ~> - @add-file file - @loading = false + @go-root = ~> + if @folder != null + @folder = null + @hierarchy-folders = [] @update! - else - flag := true + @load! + + @load = ~> + @folders = [] + @files = [] + @more-folders = false + @more-files = false + @loading = true + @update! - function contains(parent, child) - node = child.parent-node - while node? - if node == parent - return true - node = node.parent-node - return false + load-folders = null + load-files = null + + folders-max = 30 + files-max = 30 + + # フォルダ一覧å–å¾— + @api \drive/folders do + folder_id: if @folder? then @folder.id else null + limit: folders-max + 1 + .then (folders) ~> + if folders.length == folders-max + 1 + @more-folders = true + folders.pop! + load-folders := folders + complete! + .catch (err, text-status) ~> + console.error err + + # ファイル一覧å–å¾— + @api \drive/files do + folder_id: if @folder? then @folder.id else null + limit: files-max + 1 + .then (files) ~> + if files.length == files-max + 1 + @more-files = true + files.pop! + load-files := files + complete! + .catch (err, text-status) ~> + console.error err + + flag = false + complete = ~> + if flag + load-folders.for-each (folder) ~> + @add-folder folder + load-files.for-each (file) ~> + @add-file file + @loading = false + @update! + else + flag := true + + function contains(parent, child) + node = child.parent-node + while node? + if node == parent + return true + node = node.parent-node + return false + </script> +</mk-drive-browser> diff --git a/src/web/app/desktop/tags/drive/file-contextmenu.tag b/src/web/app/desktop/tags/drive/file-contextmenu.tag index 7d7dca6c92eb41691a4d254fe2a88d1f3707f4be..96779601dba614b521b2880be02d52b9ba040870 100644 --- a/src/web/app/desktop/tags/drive/file-contextmenu.tag +++ b/src/web/app/desktop/tags/drive/file-contextmenu.tag @@ -1,97 +1,103 @@ -mk-drive-browser-file-contextmenu - mk-contextmenu@ctx: ul - li(onclick={ parent.rename }): p - i.fa.fa-i-cursor - | åå‰ã‚’変更 - li(onclick={ parent.copy-url }): p - i.fa.fa-link - | URLをコピー - li: a(href={ parent.file.url + '?download' }, download={ parent.file.name }, onclick={ parent.download }) - i.fa.fa-download - | ダウンãƒãƒ¼ãƒ‰ - li.separator - li(onclick={ parent.delete }): p - i.fa.fa-trash-o - | 削除 - li.separator - li.has-child - p - | ãã®ä»–... - i.fa.fa-caret-right - ul - li(onclick={ parent.set-avatar }): p - | ã‚¢ãƒã‚¿ãƒ¼ã«è¨å®š - li(onclick={ parent.set-banner }): p - | ãƒãƒŠãƒ¼ã«è¨å®š - li(onclick={ parent.set-wallpaper }): p - | å£ç´™ã«è¨å®š - li.has-child - p - | アプリã§é–‹ã... - i.fa.fa-caret-right - ul - li(onclick={ parent.add-app }): p - | ã‚¢ãƒ—ãƒªã‚’è¿½åŠ ... +<mk-drive-browser-file-contextmenu> + <mk-contextmenu ref="ctx"> + <ul> + <li onclick="{ parent.rename }"> + <p><i class="fa fa-i-cursor"></i>åå‰ã‚’変更</p> + </li> + <li onclick="{ parent.copyUrl }"> + <p><i class="fa fa-link"></i>URLをコピー</p> + </li> + <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 onclick="{ parent.delete }"> + <p><i class="fa fa-trash-o"></i>削除</p> + </li> + <li class="separator"></li> + <li class="has-child"> + <p>ãã®ä»–...<i class="fa fa-caret-right"></i></p> + <ul> + <li onclick="{ parent.setAvatar }"> + <p>ã‚¢ãƒã‚¿ãƒ¼ã«è¨å®š</p> + </li> + <li onclick="{ parent.setBanner }"> + <p>ãƒãƒŠãƒ¼ã«è¨å®š</p> + </li> + <li onclick="{ parent.setWallpaper }"> + <p>å£ç´™ã«è¨å®š</p> + </li> + </ul> + </li> + <li class="has-child"> + <p>アプリã§é–‹ã...<i class="fa fa-caret-right"></i></p> + <ul> + <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. - @mixin \api - @mixin \i - @mixin \update-avatar - @mixin \update-banner - @mixin \update-wallpaper - @mixin \input-dialog - @mixin \NotImplementedException + @browser = @opts.browser + @file = @opts.file - @browser = @opts.browser - @file = @opts.file + @on \mount ~> + @refs.ctx.on \closed ~> + @trigger \closed + @unmount! - @on \mount ~> - @refs.ctx.on \closed ~> - @trigger \closed - @unmount! + @open = (pos) ~> + @refs.ctx.open pos - @open = (pos) ~> - @refs.ctx.open pos + @rename = ~> + @refs.ctx.close! - @rename = ~> - @refs.ctx.close! + name <~ @input-dialog do + 'ファイルåã®å¤‰æ›´' + 'æ–°ã—ã„ファイルåを入力ã—ã¦ãã ã•ã„' + @file.name - name <~ @input-dialog do - 'ファイルåã®å¤‰æ›´' - 'æ–°ã—ã„ファイルåを入力ã—ã¦ãã ã•ã„' - @file.name + @api \drive/files/update do + file_id: @file.id + name: name + .then ~> + # something + .catch (err) ~> + console.error err - @api \drive/files/update do - file_id: @file.id - name: name - .then ~> - # something - .catch (err) ~> - console.error err + @copy-url = ~> + @NotImplementedException! - @copy-url = ~> - @NotImplementedException! + @download = ~> + @refs.ctx.close! - @download = ~> - @refs.ctx.close! + @set-avatar = ~> + @refs.ctx.close! + @update-avatar @I, (i) ~> + @update-i i + , @file - @set-avatar = ~> - @refs.ctx.close! - @update-avatar @I, (i) ~> - @update-i i - , @file + @set-banner = ~> + @refs.ctx.close! + @update-banner @I, (i) ~> + @update-i i + , @file - @set-banner = ~> - @refs.ctx.close! - @update-banner @I, (i) ~> - @update-i i - , @file + @set-wallpaper = ~> + @refs.ctx.close! + @update-wallpaper @I, (i) ~> + @update-i i + , @file - @set-wallpaper = ~> - @refs.ctx.close! - @update-wallpaper @I, (i) ~> - @update-i i - , @file - - @add-app = ~> - @NotImplementedException! + @add-app = ~> + @NotImplementedException! + </script> +</mk-drive-browser-file-contextmenu> diff --git a/src/web/app/desktop/tags/drive/file.tag b/src/web/app/desktop/tags/drive/file.tag index 1702bb65016c9a55b8986f2459bf04e2c760192c..8daa54983d287bde6773d0d30de29cc612c62f15 100644 --- a/src/web/app/desktop/tags/drive/file.tag +++ b/src/web/app/desktop/tags/drive/file.tag @@ -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 }) - div.label(if={ I.avatar_id == file.id }) - img(src='/_/resources/label.svg') - p ã‚¢ãƒã‚¿ãƒ¼ - div.label(if={ I.banner_id == file.id }) - img(src='/_/resources/label.svg') - p ãƒãƒŠãƒ¼ - div.label(if={ I.data.wallpaper == file.id }) - img(src='/_/resources/label.svg') - p å£ç´™ - div.thumbnail: img(src={ file.url + '?thumbnail&size=128' }, alt='') - p.name - span { file.name.lastIndexOf('.') != -1 ? file.name.substr(0, file.name.lastIndexOf('.')) : file.name } - span.ext(if={ file.name.lastIndexOf('.') != -1 }) { file.name.substr(file.name.lastIndexOf('.')) } - -style. - display block - margin 4px - padding 8px 0 0 0 - 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) +<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 class="label" if="{ I.avatar_id == file.id }"><img src="/_/resources/label.svg"/> + <p>ã‚¢ãƒã‚¿ãƒ¼</p> + </div> + <div class="label" if="{ I.banner_id == file.id }"><img src="/_/resources/label.svg"/> + <p>ãƒãƒŠãƒ¼</p> + </div> + <div class="label" if="{ I.data.wallpaper == file.id }"><img src="/_/resources/label.svg"/> + <p>å£ç´™</p> + </div> + <div class="thumbnail"><img src="{ file.url + '?thumbnail&size=128' }" alt=""/></div> + <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> + <style type="stylus"> + :scope + display block + margin 4px + padding 8px 0 0 0 + width 144px + height 180px border-radius 4px - > .label - position absolute - top 0 - left 0 - pointer-events none - - &:before - content "" - display block - position absolute - z-index 1 - top 0 - left 57px - width 28px - height 8px - background #0c7ac9 - - &:after - content "" - display block - 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 - -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 - if @file._selected - @browser.trigger \selected @file + &, * + 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 + + > .label + position absolute + top 0 + left 0 + pointer-events none + + &:before + content "" + display block + position absolute + z-index 1 + top 0 + left 57px + width 28px + height 8px + background #0c7ac9 + + &:after + content "" + display block + 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 - @browser.files.for-each (file) ~> - file._selected = false - @file._selected = true - @browser.trigger \change-selection @file - - @oncontextmenu = (e) ~> - e.prevent-default! - e.stop-immediate-propagation! - - @is-contextmenu-showing = true - @update! - ctx = document.body.append-child document.create-element \mk-drive-browser-file-contextmenu - 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 + if @file._selected + @browser.trigger \selected @file + else + @browser.files.for-each (file) ~> + file._selected = false + @file._selected = true + @browser.trigger \change-selection @file + + @oncontextmenu = (e) ~> + e.prevent-default! + e.stop-immediate-propagation! + + @is-contextmenu-showing = true @update! - return false - - @ondragstart = (e) ~> - e.data-transfer.effect-allowed = \move - e.data-transfer.set-data 'text' JSON.stringify do - type: \file - id: @file.id - file: @file - @is-dragging = true - - # 親ブラウザã«å¯¾ã—ã¦ã€ãƒ‰ãƒ©ãƒƒã‚°ãŒé–‹å§‹ã•ã‚ŒãŸãƒ•ãƒ©ã‚°ã‚’ç«‹ã¦ã‚‹ - # (=ã‚ãªãŸã®åä¾›ãŒã€ãƒ‰ãƒ©ãƒƒã‚°ã‚’開始ã—ã¾ã—ãŸã‚ˆ) - @browser.is-drag-source = true - - @ondragend = (e) ~> - @is-dragging = false - @browser.is-drag-source = 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) ~> + e.data-transfer.effect-allowed = \move + e.data-transfer.set-data 'text' JSON.stringify do + type: \file + id: @file.id + file: @file + @is-dragging = true + + # 親ブラウザã«å¯¾ã—ã¦ã€ãƒ‰ãƒ©ãƒƒã‚°ãŒé–‹å§‹ã•ã‚ŒãŸãƒ•ãƒ©ã‚°ã‚’ç«‹ã¦ã‚‹ + # (=ã‚ãªãŸã®åä¾›ãŒã€ãƒ‰ãƒ©ãƒƒã‚°ã‚’開始ã—ã¾ã—ãŸã‚ˆ) + @browser.is-drag-source = true + + @ondragend = (e) ~> + @is-dragging = false + @browser.is-drag-source = false + </script> +</mk-drive-browser-file> diff --git a/src/web/app/desktop/tags/drive/folder-contextmenu.tag b/src/web/app/desktop/tags/drive/folder-contextmenu.tag index 67fb1047b70a62dea7fd32d4ed5a31fc8e670658..eb50e51c68a96e0cdaf51b18bfe143f663eca2a8 100644 --- a/src/web/app/desktop/tags/drive/folder-contextmenu.tag +++ b/src/web/app/desktop/tags/drive/folder-contextmenu.tag @@ -1,62 +1,66 @@ -mk-drive-browser-folder-contextmenu - mk-contextmenu@ctx: ul - li(onclick={ parent.move }): p - i.fa.fa-arrow-right - | ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ã¸ç§»å‹• - li(onclick={ parent.new-window }): p - i.fa.fa-share-square-o - | æ–°ã—ã„ウィンドウã§è¡¨ç¤º - li.separator - li(onclick={ parent.rename }): p - i.fa.fa-i-cursor - | åå‰ã‚’変更 - li.separator - li(onclick={ parent.delete }): p - i.fa.fa-trash-o - | 削除 - -script. - @mixin \api - @mixin \input-dialog - - @browser = @opts.browser - @folder = @opts.folder - - @open = (pos) ~> - @refs.ctx.open pos - - @refs.ctx.on \closed ~> - @trigger \closed - @unmount! - - @move = ~> - @browser.move @folder.id - @refs.ctx.close! - - @new-window = ~> - @browser.new-window @folder.id - @refs.ctx.close! - - @create-folder = ~> - @browser.create-folder! - @refs.ctx.close! - - @upload = ~> - @browser.select-lcoal-file! - @refs.ctx.close! - - @rename = ~> - @refs.ctx.close! - - name <~ @input-dialog do - 'フォルダåã®å¤‰æ›´' - 'æ–°ã—ã„フォルダåを入力ã—ã¦ãã ã•ã„' - @folder.name - - @api \drive/folders/update do - folder_id: @folder.id - name: name - .then ~> - # something - .catch (err) ~> - console.error err +<mk-drive-browser-folder-contextmenu> + <mk-contextmenu ref="ctx"> + <ul> + <li onclick="{ parent.move }"> + <p><i class="fa fa-arrow-right"></i>ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ã¸ç§»å‹•</p> + </li> + <li onclick="{ parent.newWindow }"> + <p><i class="fa fa-share-square-o"></i>æ–°ã—ã„ウィンドウã§è¡¨ç¤º</p> + </li> + <li class="separator"></li> + <li onclick="{ parent.rename }"> + <p><i class="fa fa-i-cursor"></i>åå‰ã‚’変更</p> + </li> + <li class="separator"></li> + <li onclick="{ parent.delete }"> + <p><i class="fa fa-trash-o"></i>削除</p> + </li> + </ul> + </mk-contextmenu> + <script> + @mixin \api + @mixin \input-dialog + + @browser = @opts.browser + @folder = @opts.folder + + @open = (pos) ~> + @refs.ctx.open pos + + @refs.ctx.on \closed ~> + @trigger \closed + @unmount! + + @move = ~> + @browser.move @folder.id + @refs.ctx.close! + + @new-window = ~> + @browser.new-window @folder.id + @refs.ctx.close! + + @create-folder = ~> + @browser.create-folder! + @refs.ctx.close! + + @upload = ~> + @browser.select-lcoal-file! + @refs.ctx.close! + + @rename = ~> + @refs.ctx.close! + + name <~ @input-dialog do + 'フォルダåã®å¤‰æ›´' + 'æ–°ã—ã„フォルダåを入力ã—ã¦ãã ã•ã„' + @folder.name + + @api \drive/folders/update do + folder_id: @folder.id + name: name + .then ~> + # something + .catch (err) ~> + console.error err + </script> +</mk-drive-browser-folder-contextmenu> diff --git a/src/web/app/desktop/tags/drive/folder.tag b/src/web/app/desktop/tags/drive/folder.tag index 0f3b06d5433c87ebf0e2be6e9129a894c201521c..ddeb21027b8f823301dfd527e4d538bcf3db16a4 100644 --- a/src/web/app/desktop/tags/drive/folder.tag +++ b/src/web/app/desktop/tags/drive/folder.tag @@ -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 }) - p.name - i.fa.fa-fw(class={ fa-folder-o: !hover, fa-folder-open-o: hover }) - | { folder.name } - -style. - display block - margin 4px - padding 8px - width 144px - 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) +<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 class="name"><i class="fa fa-fw { fa-folder-o: !hover, fa-folder-open-o: hover }"></i>{ folder.name }</p> + <style type="stylus"> + :scope + display block + margin 4px + padding 8px + width 144px + height 64px + background lighten($theme-color, 95%) border-radius 4px - &[data-draghover='true'] - background lighten($theme-color, 90%) + &, * + 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 + + &[data-draghover='true'] + background lighten($theme-color, 90%) + + > .name + margin 0 + font-size 0.9em + color darken($theme-color, 30%) + + > i + margin-right 4px + margin-left 2px + text-align left + + </style> + <script> + @mixin \api + @mixin \dialog + + @folder = @opts.folder + @browser = @parent + + @title = @folder.name + @hover = false + @draghover = false + @is-contextmenu-showing = false - > .name - margin 0 - font-size 0.9em - color darken($theme-color, 30%) + @onclick = ~> + @browser.move @folder - > i - margin-right 4px - margin-left 2px - text-align left + @onmouseover = ~> + @hover = true -script. - @mixin \api - @mixin \dialog + @onmouseout = ~> + @hover = false - @folder = @opts.folder - @browser = @parent + @ondragover = (e) ~> + e.prevent-default! + e.stop-propagation! - @title = @folder.name - @hover = false - @draghover = false - @is-contextmenu-showing = false + # 自分自身ãŒãƒ‰ãƒ©ãƒƒã‚°ã•ã‚Œã¦ã„ãªã„å ´åˆ + if !@is-dragging + # ドラッグã•ã‚Œã¦ããŸã‚‚ã®ãŒãƒ•ã‚¡ã‚¤ãƒ«ã ã£ãŸã‚‰ + if e.data-transfer.effect-allowed == \all + e.data-transfer.drop-effect = \copy + else + e.data-transfer.drop-effect = \move + else + # 自分自身ã«ã¯ãƒ‰ãƒãƒƒãƒ—ã•ã›ãªã„ + e.data-transfer.drop-effect = \none + return false - @onclick = ~> - @browser.move @folder + @ondragenter = ~> + if !@is-dragging + @draghover = true - @onmouseover = ~> - @hover = true + @ondragleave = ~> + @draghover = false - @onmouseout = ~> - @hover = false + @ondrop = (e) ~> + e.stop-propagation! + @draghover = false - @ondragover = (e) ~> - e.prevent-default! - e.stop-propagation! + # ファイルã ã£ãŸã‚‰ + if e.data-transfer.files.length > 0 + Array.prototype.for-each.call e.data-transfer.files, (file) ~> + @browser.upload file, @folder + return false - # 自分自身ãŒãƒ‰ãƒ©ãƒƒã‚°ã•ã‚Œã¦ã„ãªã„å ´åˆ - if !@is-dragging - # ドラッグã•ã‚Œã¦ããŸã‚‚ã®ãŒãƒ•ã‚¡ã‚¤ãƒ«ã ã£ãŸã‚‰ - if e.data-transfer.effect-allowed == \all - e.data-transfer.drop-effect = \copy - else - e.data-transfer.drop-effect = \move - else - # 自分自身ã«ã¯ãƒ‰ãƒãƒƒãƒ—ã•ã›ãªã„ - e.data-transfer.drop-effect = \none - return false + # データå–å¾— + data = e.data-transfer.get-data 'text' + if !data? + return false - @ondragenter = ~> - if !@is-dragging - @draghover = true + # パース + 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: @folder.id + .then ~> + # something + .catch (err, text-status) ~> + console.error err + + # (ドライブã®)フォルダーã ã£ãŸã‚‰ + else if obj.type == \folder + 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 + ] - @ondragleave = ~> - @draghover = false + return false - @ondrop = (e) ~> - e.stop-propagation! - @draghover = false + @ondragstart = (e) ~> + e.data-transfer.effect-allowed = \move + e.data-transfer.set-data 'text' JSON.stringify do + type: \folder + id: @folder.id + @is-dragging = true - # ファイルã ã£ãŸã‚‰ - if e.data-transfer.files.length > 0 - Array.prototype.for-each.call e.data-transfer.files, (file) ~> - @browser.upload file, @folder - return false + # 親ブラウザã«å¯¾ã—ã¦ã€ãƒ‰ãƒ©ãƒƒã‚°ãŒé–‹å§‹ã•ã‚ŒãŸãƒ•ãƒ©ã‚°ã‚’ç«‹ã¦ã‚‹ + # (=ã‚ãªãŸã®åä¾›ãŒã€ãƒ‰ãƒ©ãƒƒã‚°ã‚’開始ã—ã¾ã—ãŸã‚ˆ) + @browser.is-drag-source = true - # データå–å¾— - data = e.data-transfer.get-data 'text' - if !data? - return false + @ondragend = (e) ~> + @is-dragging = false + @browser.is-drag-source = 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: @folder.id - .then ~> - # something - .catch (err, text-status) ~> - console.error err - - # (ドライブã®)フォルダーã ã£ãŸã‚‰ - else if obj.type == \folder - 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 - ] - - return false - - @ondragstart = (e) ~> - e.data-transfer.effect-allowed = \move - e.data-transfer.set-data 'text' JSON.stringify do - type: \folder - id: @folder.id - @is-dragging = true - - # 親ブラウザã«å¯¾ã—ã¦ã€ãƒ‰ãƒ©ãƒƒã‚°ãŒé–‹å§‹ã•ã‚ŒãŸãƒ•ãƒ©ã‚°ã‚’ç«‹ã¦ã‚‹ - # (=ã‚ãªãŸã®åä¾›ãŒã€ãƒ‰ãƒ©ãƒƒã‚°ã‚’開始ã—ã¾ã—ãŸã‚ˆ) - @browser.is-drag-source = true - - @ondragend = (e) ~> - @is-dragging = false - @browser.is-drag-source = false - - @oncontextmenu = (e) ~> - e.prevent-default! - e.stop-immediate-propagation! - - @is-contextmenu-showing = true - @update! - ctx = document.body.append-child document.create-element \mk-drive-browser-folder-contextmenu - 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 + @oncontextmenu = (e) ~> + e.prevent-default! + e.stop-immediate-propagation! + + @is-contextmenu-showing = true @update! + ctx = document.body.append-child document.create-element \mk-drive-browser-folder-contextmenu + 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> diff --git a/src/web/app/desktop/tags/drive/nav-folder.tag b/src/web/app/desktop/tags/drive/nav-folder.tag index 398a26a80b3d9573af96022aa27c09e6895aec45..34d6efdf58cfc5481279c8757b2797836158d34d 100644 --- a/src/web/app/desktop/tags/drive/nav-folder.tag +++ b/src/web/app/desktop/tags/drive/nav-folder.tag @@ -1,96 +1,97 @@ -mk-drive-browser-nav-folder(data-draghover={ draghover }, onclick={ onclick }, ondragover={ ondragover }, ondragenter={ ondragenter }, ondragleave={ ondragleave }, ondrop={ ondrop }) - i.fa.fa-cloud(if={ folder == null }) - span { folder == null ? 'ドライブ' : folder.name } +<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> + <style type="stylus"> + :scope + &[data-draghover] + background #eee + + </style> + <script> + @mixin \api + + # Riotã®ãƒã‚°ã§nullを渡ã—ã¦ã‚‚""ã«ãªã‚‹ + # https://github.com/riot/riot/issues/2080 + #@folder = @opts.folder + @folder = if @opts.folder? and @opts.folder != '' then @opts.folder else null + @browser = @parent -style. - &[data-draghover] - background #eee + @hover = false -script. - @mixin \api + @onclick = ~> + @browser.move @folder - # 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 + @onmouseover = ~> + @hover = true - @hover = false + @onmouseout = ~> + @hover = false - @onclick = ~> - @browser.move @folder + @ondragover = (e) ~> + e.prevent-default! + e.stop-propagation! - @onmouseover = ~> - @hover = true + # ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ãŒãƒ«ãƒ¼ãƒˆã‹ã¤ã‚«ãƒ¬ãƒ³ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãªã‚‰ãƒ‰ãƒãƒƒãƒ—ç¦æ¢ + 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 - @onmouseout = ~> - @hover = false + @ondragenter = ~> + if @folder != null or @browser.folder != null + @draghover = true - @ondragover = (e) ~> - e.prevent-default! - e.stop-propagation! - - # ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ãŒãƒ«ãƒ¼ãƒˆã‹ã¤ã‚«ãƒ¬ãƒ³ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãªã‚‰ãƒ‰ãƒãƒƒãƒ—ç¦æ¢ - if @folder == null and @browser.folder == null - e.data-transfer.drop-effect = \none - # ドラッグã•ã‚Œã¦ããŸã‚‚ã®ãŒãƒ•ã‚¡ã‚¤ãƒ«ã ã£ãŸã‚‰ - else if e.data-transfer.effect-allowed == \all - e.data-transfer.drop-effect = \copy - 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 + @ondragleave = ~> + if @folder != null or @browser.folder != null + @draghover = false + + @ondrop = (e) ~> + e.stop-propagation! @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 + + # データå–å¾— + data = e.data-transfer.get-data 'text' + if !data? + return false - # ファイルã ã£ãŸã‚‰ - if e.data-transfer.files.length > 0 - Array.prototype.for-each.call e.data-transfer.files, (file) ~> - @browser.upload file, @folder - 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 - # データå–å¾— - 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> diff --git a/src/web/app/desktop/tags/ellipsis-icon.tag b/src/web/app/desktop/tags/ellipsis-icon.tag index 5d18bc04732708c5e71734558cfd69e91ca4f60d..34731bb797c29c8f49d423663842193252edd6e3 100644 --- a/src/web/app/desktop/tags/ellipsis-icon.tag +++ b/src/web/app/desktop/tags/ellipsis-icon.tag @@ -1,34 +1,41 @@ -mk-ellipsis-icon - div - div - div - -style. - display block - width 70px - margin 0 auto - text-align center - - > div - display inline-block - 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) - animation-delay 0s - - &:nth-child(2) - margin 0 6px - animation-delay 0.16s - - &:nth-child(3) - animation-delay 0.32s - - @keyframes bounce - 0%, 80%, 100% - transform scale(0) - 40% - transform scale(1) +<mk-ellipsis-icon> + <div></div> + <div></div> + <div></div> + <style type="stylus"> + :scope + display block + width 70px + margin 0 auto + text-align center + + > div + display inline-block + 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) + animation-delay 0s + + &:nth-child(2) + margin 0 6px + animation-delay 0.16s + + &:nth-child(3) + animation-delay 0.32s + + @keyframes bounce + 0%, 80%, 100% + transform scale(0) + 40% + transform scale(1) + + + + + + </style> +</mk-ellipsis-icon> diff --git a/src/web/app/desktop/tags/follow-button.tag b/src/web/app/desktop/tags/follow-button.tag index 41bd1f0e12544754a00bd9a446682e58844bef68..300a5fe03584f785f4c90430484e22bde0a2038f 100644 --- a/src/web/app/desktop/tags/follow-button.tag +++ b/src/web/app/desktop/tags/follow-button.tag @@ -1,127 +1,124 @@ -mk-follow-button - button(if={ !init }, class={ wait: wait, follow: !user.is_following, unfollow: user.is_following }, - onclick={ onclick }, - disabled={ wait }, - title={ user.is_following ? 'フォãƒãƒ¼è§£é™¤' : 'フォãƒãƒ¼ã™ã‚‹' }) - i.fa.fa-minus(if={ !wait && user.is_following }) - 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. - display block - - > button - > .init - display block - cursor pointer - padding 0 - margin 0 - width 32px - height 32px - font-size 1em - outline none - border-radius 4px - - * - pointer-events none - - &: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 - - &.follow - color #888 - background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) - border solid 1px #e2e2e2 - - &:hover - background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) - border-color #dcdcdc - - &:active - background #ececec - border-color #dcdcdc - - &.unfollow - 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%) - - &: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 - - &.wait - cursor wait !important - opacity 0.7 - -script. - @mixin \api - @mixin \is-promise - @mixin \stream - - @user = null - @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user - @init = true - @wait = false - - @on \mount ~> - @user-promise.then (user) ~> - @user = user - @init = false - @update! - @stream.on \follow @on-stream-follow - @stream.on \unfollow @on-stream-unfollow - - @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 +<mk-follow-button> + <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> + <div class="init" if="{ init }"><i class="fa fa-spinner fa-pulse fa-fw"></i></div> + <style type="stylus"> + :scope + display block + + > button + > .init + display block + cursor pointer + padding 0 + margin 0 + width 32px + height 32px + font-size 1em + outline none + border-radius 4px + + * + pointer-events none + + &: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 + + &.follow + color #888 + background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) + border solid 1px #e2e2e2 + + &:hover + background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) + border-color #dcdcdc + + &:active + background #ececec + border-color #dcdcdc + + &.unfollow + 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%) + + &: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 + + &.wait + cursor wait !important + opacity 0.7 + + </style> + <script> + @mixin \api + @mixin \is-promise + @mixin \stream + + @user = null + @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user + @init = true + @wait = false + + @on \mount ~> + @user-promise.then (user) ~> + @user = user + @init = false @update! - else - @api \following/create do - user_id: @user.id - .then ~> - @user.is_following = true - .catch (err) -> - console.error err - .then ~> - @wait = false + @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! + 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> diff --git a/src/web/app/desktop/tags/following-setuper.tag b/src/web/app/desktop/tags/following-setuper.tag index 9b75a251e05b4bda750d547d14c36745f180eced..6e8e40a2b16f2a3fabeedbd530465f15c871bf28 100644 --- a/src/web/app/desktop/tags/following-setuper.tag +++ b/src/web/app/desktop/tags/following-setuper.tag @@ -1,163 +1,163 @@ -mk-following-setuper - p.title æ°—ã«ãªã‚‹ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’フォãƒãƒ¼: - div.users(if={ !loading && users.length > 0 }) - div.user(each={ users }) - a.avatar-anchor(href={ CONFIG.url + '/' + username }) - img.avatar(src={ avatar_url + '?thumbnail&size=42' }, alt='', data-user-preview={ id }) - div.body - a.name(href={ CONFIG.url + '/' + username }, target='_blank', data-user-preview={ id }) { name } - p.username @{ username } - mk-follow-button(user={ this }) - p.empty(if={ !loading && users.length == 0 }) - | ãŠã™ã™ã‚ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚ - p.loading(if={ loading }) - i.fa.fa-spinner.fa-pulse.fa-fw - | èªã¿è¾¼ã‚“ã§ã„ã¾ã™ - mk-ellipsis - a.refresh(onclick={ refresh }) ã‚‚ã£ã¨è¦‹ã‚‹ - 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 "" +<mk-following-setuper> + <p class="title">æ°—ã«ãªã‚‹ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’フォãƒãƒ¼:</p> + <div class="users" if="{ !loading && users.length > 0 }"> + <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> + <div class="body"><a class="name" href="{ CONFIG.url + '/' + username }" target="_blank" data-user-preview="{ id }">{ name }</a> + <p class="username">@{ username }</p> + </div> + <mk-follow-button user="{ this }"></mk-follow-button> + </div> + </div> + <p class="empty" if="{ !loading && users.length == 0 }">ãŠã™ã™ã‚ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚</p> + <p class="loading" if="{ loading }"><i class="fa fa-spinner fa-pulse fa-fw"></i>èªã¿è¾¼ã‚“ã§ã„ã¾ã™ + <mk-ellipsis></mk-ellipsis> + </p><a class="refresh" onclick="{ refresh }">ã‚‚ã£ã¨è¦‹ã‚‹</a> + <button class="close" onclick="{ close }" title="é–‰ã˜ã‚‹"><i class="fa fa-times"></i></button> + <style type="stylus"> + :scope display block - clear both - - > .user - padding 16px - width 238px - float left - - &:after - content "" + padding 24px + background #fff + + > .title + margin 0 0 12px 0 + font-size 1em + font-weight bold + color #888 + + > .users + &:after + content "" + display block + clear both + + > .user + padding 16px + width 238px + float left + + &:after + content "" + display block + 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 - clear both + margin 0 8px 0 0 + text-align right + font-size 0.9em + color #999 - > .avatar-anchor + > .close + cursor pointer 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 + 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 - > .username - margin 0 - font-size 15px - line-height 16px - color #ccc + &:active + color #222 + + > i + padding 14px + + </style> + <script> + @mixin \api + @mixin \user-preview - > 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 - - &: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 - @update! - - @api \users/recommendation do - limit: @limit - offset: @limit * @page - .then (users) ~> - @loading = false - @users = users + @loading = true + + @limit = 6users + @page = 0 + + @on \mount ~> + @load! + + @load = ~> + @loading = true + @users = null @update! - .catch (err, text-status) -> - console.error err - - @refresh = ~> - if @users.length < @limit - @page = 0 - else - @page++ - @load! - - @close = ~> - @unmount! + + @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++ + @load! + + @close = ~> + @unmount! + </script> +</mk-following-setuper> diff --git a/src/web/app/desktop/tags/go-top.tag b/src/web/app/desktop/tags/go-top.tag index a11f4a36409541f2967fdd00a90930c4dc1b5d83..d43e68ea904fe1a8e59acfa3b90a068b08a9c709 100644 --- a/src/web/app/desktop/tags/go-top.tag +++ b/src/web/app/desktop/tags/go-top.tag @@ -1,15 +1,14 @@ -mk-go-top - button.hidden(title='一番上ã¸') - i.fa.fa-angle-up +<mk-go-top> + <button class="hidden" title="一番上ã¸"><i class="fa fa-angle-up"></i></button> + <script> + window.add-event-listener \load @on-scroll + window.add-event-listener \scroll @on-scroll + window.add-event-listener \resize @on-scroll -script. - - window.add-event-listener \load @on-scroll - window.add-event-listener \scroll @on-scroll - window.add-event-listener \resize @on-scroll - - @on-scroll = ~> - if $ window .scroll-top! > 500px - @remove-class \hidden - else - @add-class \hidden + @on-scroll = ~> + if $ window .scroll-top! > 500px + @remove-class \hidden + else + @add-class \hidden + </script> +</mk-go-top> diff --git a/src/web/app/desktop/tags/home-widgets/broadcast.tag b/src/web/app/desktop/tags/home-widgets/broadcast.tag index 0e21adec4892c06925e867b5dce21875abd24db3..dda71218ab44543af36022665449b2b1f3ba0385 100644 --- a/src/web/app/desktop/tags/home-widgets/broadcast.tag +++ b/src/web/app/desktop/tags/home-widgets/broadcast.tag @@ -1,75 +1,83 @@ -mk-broadcast-home-widget - div.icon - 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.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.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.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.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') +<mk-broadcast-home-widget> + <div class="icon"> + <svg height="32" version="1.1" viewBox="0 0 32 32" width="32"> + <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 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 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 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 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 開発者募集ä¸ï¼ - p: a(href='https://github.com/syuilo/misskey', target='_blank') Misskeyã¯ã‚ªãƒ¼ãƒ—ンソースã§é–‹ç™ºã•ã‚Œã¦ã„ã¾ã™ã€‚リãƒã‚¸ãƒˆãƒªã¯ã“ã¡ã‚‰ã€‚ + &:after + content "" + display block + clear both -style. - display block - padding 10px 10px 10px 50px - background transparent - border-color #4078c0 !important + > .icon + display block + float left + margin-left -40px - &:after - content "" - display block - clear both + > svg + fill currentColor + color #4078c0 - > .icon - display block - float left - margin-left -40px + > .wave + opacity 1 - > 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 - &.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 - @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 + > h1 + margin 0 + font-size 0.95em + font-weight normal + color #4078c0 - > h1 - 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 - > p - display block - z-index 1 - margin 0 - font-size 0.7em - color #555 + a + color #555 + + + + - a - color #555 + </style> +</mk-broadcast-home-widget> diff --git a/src/web/app/desktop/tags/home-widgets/calendar.tag b/src/web/app/desktop/tags/home-widgets/calendar.tag index 87c65729d39b0da7917cb214207ca0a52b5c224f..affa55c96bc12ef184cf8df9e2f6717114216847 100644 --- a/src/web/app/desktop/tags/home-widgets/calendar.tag +++ b/src/web/app/desktop/tags/home-widgets/calendar.tag @@ -1,147 +1,148 @@ -mk-calendar-home-widget(data-special={ special }) - div.calendar(data-is-holiday={ is-holiday }) - p.month-and-year - span.year { year }å¹´ - span.month { month }月 - p.day { day }æ—¥ - p.week-day { week-day }曜日 - div.info - div - p - | 今日: - b { day-p.to-fixed(1) }% - div.meter - div.val(style={ 'width:' + day-p + '%' }) - - div - p - | 今月: - b { month-p.to-fixed(1) }% - div.meter - div.val(style={ 'width:' + month-p + '%' }) - - div - p - | 今年: - b { year-p.to-fixed(1) }% - div.meter - div.val(style={ 'width:' + year-p + '%' }) - -style. - display block - padding 16px 0 - color #777 - background #fff - - &[data-special='on-new-years-day'] - border-color #ef95a0 !important - - &:after - content "" - display block - clear both - - > .calendar - float left - width 60% - text-align center - - &[data-is-holiday] - > .day - color #ef95a0 - - > p - margin 0 - line-height 18px - font-size 14px - - > span - margin 0 4px - - > .day - margin 10px 0 - line-height 32px - font-size 28px - - > .info - display block - float left - width 40% - padding 0 16px 0 0 - - > div - margin-bottom 8px - - &:last-child - margin-bottom 4px - - > p - margin 0 0 2px 0 - font-size 12px - line-height 18px - color #888 - - > b - margin-left 2px - - > .meter - width 100% - overflow hidden - background #eee - border-radius 8px - - > .val - height 4px - background $theme-color - - &:nth-child(1) - > .meter > .val - background #f7796c - - &:nth-child(2) - > .meter > .val - background #a1de41 - - &:nth-child(3) - > .meter > .val - background #41ddde - -script. - @draw = ~> - now = new Date! - nd = now.get-date! - nm = now.get-month! - ny = now.get-full-year! - - @year = ny - @month = nm + 1 - @day = nd - @week-day = [\æ—¥ \月 \ç« \æ°´ \木 \金 \土][now.get-day!] - - @day-numer = (now - (new Date ny, nm, nd)) - @day-denom = 1000ms * 60s * 60m * 24h - @month-numer = (now - (new Date ny, nm, 1)) - @month-denom = (new Date ny, nm + 1, 1) - (new Date ny, nm, 1) - @year-numer = (now - (new Date ny, 0, 1)) - @year-denom = (new Date ny + 1, 0, 1) - (new Date ny, 0, 1) - - @day-p = @day-numer / @day-denom * 100 - @month-p = @month-numer / @month-denom * 100 - @year-p = @year-numer / @year-denom * 100 - - @is-holiday = - (now.get-day! == 0 or now.get-day! == 6) - - @special = - | nm == 0 and nd == 1 => \on-new-years-day - | _ => false - - @update! - - @draw! - - @on \mount ~> - @clock = set-interval @draw, 1000ms - - @on \unmount ~> - clear-interval @clock +<mk-calendar-home-widget data-special="{ special }"> + <div class="calendar" data-is-holiday="{ isHoliday }"> + <p class="month-and-year"><span class="year">{ year }å¹´</span><span class="month">{ month }月</span></p> + <p class="day">{ day }æ—¥</p> + <p class="week-day">{ weekDay }曜日</p> + </div> + <div class="info"> + <div> + <p>今日:<b>{ dayP.toFixed(1) }%</b></p> + <div class="meter"> + <div class="val" style="{ 'width:' + dayP + '%' }"></div> + </div> + </div> + <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 + + &[data-special='on-new-years-day'] + border-color #ef95a0 !important + + &:after + content "" + display block + clear both + + > .calendar + float left + width 60% + text-align center + + &[data-is-holiday] + > .day + color #ef95a0 + + > p + margin 0 + line-height 18px + font-size 14px + + > span + margin 0 4px + + > .day + margin 10px 0 + line-height 32px + font-size 28px + + > .info + display block + float left + width 40% + padding 0 16px 0 0 + + > div + margin-bottom 8px + + &:last-child + margin-bottom 4px + + > p + margin 0 0 2px 0 + font-size 12px + line-height 18px + color #888 + + > b + margin-left 2px + + > .meter + width 100% + overflow hidden + background #eee + border-radius 8px + + > .val + height 4px + background $theme-color + + &:nth-child(1) + > .meter > .val + background #f7796c + + &:nth-child(2) + > .meter > .val + background #a1de41 + + &:nth-child(3) + > .meter > .val + background #41ddde + + </style> + <script> + @draw = ~> + now = new Date! + nd = now.get-date! + nm = now.get-month! + ny = now.get-full-year! + + @year = ny + @month = nm + 1 + @day = nd + @week-day = [\æ—¥ \月 \ç« \æ°´ \木 \金 \土][now.get-day!] + + @day-numer = (now - (new Date ny, nm, nd)) + @day-denom = 1000ms * 60s * 60m * 24h + @month-numer = (now - (new Date ny, nm, 1)) + @month-denom = (new Date ny, nm + 1, 1) - (new Date ny, nm, 1) + @year-numer = (now - (new Date ny, 0, 1)) + @year-denom = (new Date ny + 1, 0, 1) - (new Date ny, 0, 1) + + @day-p = @day-numer / @day-denom * 100 + @month-p = @month-numer / @month-denom * 100 + @year-p = @year-numer / @year-denom * 100 + + @is-holiday = + (now.get-day! == 0 or now.get-day! == 6) + + @special = + | nm == 0 and nd == 1 => \on-new-years-day + | _ => false + + @update! + + @draw! + + @on \mount ~> + @clock = set-interval @draw, 1000ms + + @on \unmount ~> + clear-interval @clock + </script> +</mk-calendar-home-widget> diff --git a/src/web/app/desktop/tags/home-widgets/donation.tag b/src/web/app/desktop/tags/home-widgets/donation.tag index a41bd9f8a40ce11ef2a363188a954c212f525287..01d9b20ea26d9f075891867d3f9389d548833374 100644 --- a/src/web/app/desktop/tags/home-widgets/donation.tag +++ b/src/web/app/desktop/tags/home-widgets/donation.tag @@ -1,37 +1,36 @@ -mk-donation-home-widget - article - h1 - i.fa.fa-heart - | 寄付ã®ãŠé¡˜ã„ - p - | Misskeyã®é‹å–¶ã«ã¯ãƒ‰ãƒ¡ã‚¤ãƒ³ã€ã‚µãƒ¼ãƒãƒ¼ç‰ã®ã‚³ã‚¹ãƒˆãŒæŽ›ã‹ã‚Šã¾ã™ã€‚ - | Misskeyã¯åºƒå‘Šã‚’掲載ã—ãŸã‚Šã—ãªã„ãŸã‚〠åŽå…¥ã‚’皆様ã‹ã‚‰ã®å¯„付ã«é ¼ã£ã¦ã„ã¾ã™ã€‚ - | ã‚‚ã—ã”興味ãŒã‚ã‚Œã°ã€ - a(href='/syuilo', data-user-preview='@syuilo') @syuilo - | ã¾ã§ã”連絡ãã ã•ã„。ã”å”力ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ - -style. - display block - background #fff - border-color #ead8bb !important +<mk-donation-home-widget> + <article> + <h1><i class="fa fa-heart"></i>寄付ã®ãŠé¡˜ã„</h1> + <p> + Misskeyã®é‹å–¶ã«ã¯ãƒ‰ãƒ¡ã‚¤ãƒ³ã€ã‚µãƒ¼ãƒãƒ¼ç‰ã®ã‚³ã‚¹ãƒˆãŒæŽ›ã‹ã‚Šã¾ã™ã€‚ + Misskeyã¯åºƒå‘Šã‚’掲載ã—ãŸã‚Šã—ãªã„ãŸã‚〠åŽå…¥ã‚’皆様ã‹ã‚‰ã®å¯„付ã«é ¼ã£ã¦ã„ã¾ã™ã€‚ + ã‚‚ã—ã”興味ãŒã‚ã‚Œã°ã€<a href="/syuilo" data-user-preview="@syuilo">@syuilo</a>ã¾ã§ã”連絡ãã ã•ã„。ã”å”力ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ + </p> + </article> + <style type="stylus"> + :scope + display block + background #fff + border-color #ead8bb !important - > article - padding 20px + > article + padding 20px - > h1 - margin 0 0 5px 0 - font-size 1em - color #888 + > h1 + margin 0 0 5px 0 + font-size 1em + color #888 - > i - margin-right 0.25em + > i + margin-right 0.25em - > p - display block - z-index 1 - margin 0 - font-size 0.8em - color #999 + > p + display block + z-index 1 + margin 0 + font-size 0.8em + color #999 -script. - @mixin \user-preview + </style> + <script>@mixin \user-preview</script> +</mk-donation-home-widget> diff --git a/src/web/app/desktop/tags/home-widgets/mentions.tag b/src/web/app/desktop/tags/home-widgets/mentions.tag index 0f0cd0269df888063f966395dd9513473d1a3dab..81ceff6179a2fe4dfab29d7a9ba4563c546830b1 100644 --- a/src/web/app/desktop/tags/home-widgets/mentions.tag +++ b/src/web/app/desktop/tags/home-widgets/mentions.tag @@ -1,117 +1,112 @@ -mk-mentions-home-widget - header - span(data-is-active={ mode == 'all' }, onclick={ set-mode.bind(this, 'all') }) ã™ã¹ã¦ - span(data-is-active={ mode == 'following' }, onclick={ set-mode.bind(this, 'following') }) フォãƒãƒ¼ä¸ - div.loading(if={ is-loading }) - mk-ellipsis-icon - p.empty(if={ is-empty }) - i.fa.fa-comments-o - span(if={ mode == 'all' }) ã‚ãªãŸå®›ã¦ã®æŠ•ç¨¿ã¯ã‚ã‚Šã¾ã›ã‚“。 - 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 +<mk-mentions-home-widget> + <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> + <div class="loading" if="{ isLoading }"> + <mk-ellipsis-icon></mk-ellipsis-icon> + </div> + <p class="empty" if="{ isEmpty }"><i class="fa fa-comments-o"></i><span if="{ mode == 'all' }">ã‚ãªãŸå®›ã¦ã®æŠ•ç¨¿ã¯ã‚ã‚Šã¾ã›ã‚“。</span><span if="{ mode == 'following' }">ã‚ãªãŸãŒãƒ•ã‚©ãƒãƒ¼ã—ã¦ã„るユーザーã‹ã‚‰ã®è¨€åŠã¯ã‚ã‚Šã¾ã›ã‚“。</span></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> + <style type="stylus"> + :scope display block - margin-bottom 16px - font-size 3em - color #ccc - -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 + 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 + margin-bottom 16px + font-size 3em + color #ccc + + </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! - @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/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 = ~> - current = window.scroll-y + window.inner-height - if current > document.body.offset-height - 8 - @more! - - @set-mode = (mode) ~> - @update do - mode: mode - @fetch! + @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 = ~> + current = window.scroll-y + window.inner-height + if current > document.body.offset-height - 8 + @more! + + @set-mode = (mode) ~> + @update do + mode: mode + @fetch! + </script> +</mk-mentions-home-widget> diff --git a/src/web/app/desktop/tags/home-widgets/nav.tag b/src/web/app/desktop/tags/home-widgets/nav.tag index 5b8e7e1b3c30679349afd99c9edfa490f2a2f492..7e153bc234221d0df91d977b1e9709c6f6004c1f 100644 --- a/src/web/app/desktop/tags/home-widgets/nav.tag +++ b/src/web/app/desktop/tags/home-widgets/nav.tag @@ -1,23 +1,21 @@ -mk-nav-home-widget - a(href={ CONFIG.urls.about }) Misskeyã«ã¤ã„㦠- i ・ - a(href={ CONFIG.urls.about + '/status' }) ステータス - i ・ - a(href='https://github.com/syuilo/misskey') リãƒã‚¸ãƒˆãƒª - i ・ - a(href={ CONFIG.urls.dev }) 開発者 - i ・ - a(href='https://twitter.com/misskey_xyz', target='_blank') Follow us on <i class="fa fa-twitter"></i> +<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> + <style type="stylus"> + :scope + display block + padding 16px + font-size 12px + color #aaa + background #fff -style. - display block - padding 16px - font-size 12px - color #aaa - background #fff + a + color #999 - a - color #999 + i + color #ccc - i - color #ccc + + + + + </style> +</mk-nav-home-widget> diff --git a/src/web/app/desktop/tags/home-widgets/notifications.tag b/src/web/app/desktop/tags/home-widgets/notifications.tag index 588a765d02305456be3aca582d207ba9245b713a..43baa014393e4c4c72a2a06416d493bd512c0a42 100644 --- a/src/web/app/desktop/tags/home-widgets/notifications.tag +++ b/src/web/app/desktop/tags/home-widgets/notifications.tag @@ -1,49 +1,50 @@ -mk-notifications-home-widget - p.title - i.fa.fa-bell-o - | 通知 - button(onclick={ settings }, title='通知ã®è¨å®š'): i.fa.fa-cog - mk-notifications - -style. - display block - background #fff - - > .title - z-index 1 - 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 - 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 - - > mk-notifications - max-height 300px - overflow auto - -script. - @settings = ~> - w = riot.mount document.body.append-child document.create-element \mk-settings-window .0 - w.switch \notification +<mk-notifications-home-widget> + <p class="title"><i class="fa fa-bell-o"></i>通知</p> + <button onclick="{ settings }" title="通知ã®è¨å®š"><i class="fa fa-cog"></i></button> + <mk-notifications></mk-notifications> + <style type="stylus"> + :scope + display block + background #fff + + > .title + z-index 1 + 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 + 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 + + > mk-notifications + max-height 300px + overflow auto + + </style> + <script> + @settings = ~> + w = riot.mount document.body.append-child document.create-element \mk-settings-window .0 + w.switch \notification + </script> +</mk-notifications-home-widget> diff --git a/src/web/app/desktop/tags/home-widgets/photo-stream.tag b/src/web/app/desktop/tags/home-widgets/photo-stream.tag index b9727065745995039a0fa7a4b888ec944fac250b..245427badf93bcae25cb1d8f8af7511cd10b0428 100644 --- a/src/web/app/desktop/tags/home-widgets/photo-stream.tag +++ b/src/web/app/desktop/tags/home-widgets/photo-stream.tag @@ -1,86 +1,87 @@ -mk-photo-stream-home-widget - p.title - i.fa.fa-camera - | フォトストリーム- p.initializing(if={ initializing }) - i.fa.fa-spinner.fa-pulse.fa-fw - | èªã¿è¾¼ã‚“ã§ã„ã¾ã™ - mk-ellipsis - div.stream(if={ !initializing && images.length > 0 }) - virtual(each={ image in images }) - div.img(style={ 'background-image: url(' + image.url + '?thumbnail&size=256)' }) - p.empty(if={ !initializing && images.length == 0 }) - | 写真ã¯ã‚ã‚Šã¾ã›ã‚“ +<mk-photo-stream-home-widget> + <p class="title"><i class="fa fa-camera"></i>フォトストリーム</p> + <p class="initializing" if="{ initializing }"><i class="fa fa-spinner fa-pulse fa-fw"></i>èªã¿è¾¼ã‚“ã§ã„ã¾ã™ + <mk-ellipsis></mk-ellipsis> + </p> + <div class="stream" if="{ !initializing && images.length > 0 }"> + <virtual each="{ image in images }"> + <div class="img" style="{ 'background-image: url(' + image.url + '?thumbnail&size=256)' }"></div> + </virtual> + </div> + <p class="empty" if="{ !initializing && images.length == 0 }">写真ã¯ã‚ã‚Šã¾ã›ã‚“</p> + <style type="stylus"> + :scope + display block + background #fff -style. - display block - background #fff + > .title + z-index 1 + 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 - z-index 1 - 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 - > i - margin-right 4px + > .stream + display -webkit-flex + display -moz-flex + display -ms-flex + display flex + justify-content center + flex-wrap wrap + padding 8px - > .stream - display -webkit-flex - display -moz-flex - display -ms-flex - display flex - justify-content center - flex-wrap wrap - padding 8px + > .img + flex 1 1 33% + width 33% + height 80px + background-position center center + background-size cover + background-clip content-box + border solid 2px transparent - > .img - flex 1 1 33% - width 33% - height 80px - background-position center center - background-size cover - background-clip content-box - border solid 2px transparent + > .initializing + > .empty + margin 0 + padding 16px + text-align center + color #aaa - > .initializing - > .empty - margin 0 - padding 16px - text-align center - color #aaa + > i + margin-right 4px - > i - margin-right 4px + </style> + <script> + @mixin \api + @mixin \stream -script. - @mixin \api - @mixin \stream + @images = [] + @initializing = true - @images = [] - @initializing = true + @on \mount ~> + @stream.on \drive_file_created @on-stream-drive-file-created - @on \mount ~> - @stream.on \drive_file_created @on-stream-drive-file-created + @api \drive/stream do + type: 'image/*' + limit: 9images + .then (images) ~> + @initializing = false + @images = images + @update! - @api \drive/stream do - type: 'image/*' - limit: 9images - .then (images) ~> - @initializing = false - @images = images - @update! + @on \unmount ~> + @stream.off \drive_file_created @on-stream-drive-file-created - @on \unmount ~> - @stream.off \drive_file_created @on-stream-drive-file-created - - @on-stream-drive-file-created = (file) ~> - if /^image\/.+$/.test file.type - @images.unshift file - if @images.length > 9 - @images.pop! - @update! + @on-stream-drive-file-created = (file) ~> + if /^image\/.+$/.test file.type + @images.unshift file + if @images.length > 9 + @images.pop! + @update! + </script> +</mk-photo-stream-home-widget> diff --git a/src/web/app/desktop/tags/home-widgets/profile.tag b/src/web/app/desktop/tags/home-widgets/profile.tag index ae8d43c645ab3adf8f0567444af047b8685c9b8b..24a0035c4cf1523a465e4eafdb613e8428aba860 100644 --- a/src/web/app/desktop/tags/home-widgets/profile.tag +++ b/src/web/app/desktop/tags/home-widgets/profile.tag @@ -1,55 +1,56 @@ -mk-profile-home-widget - div.banner(style={ I.banner_url ? 'background-image: url(' + I.banner_url + '?thumbnail&size=256)' : '' }, onclick={ set-banner }) - img.avatar(src={ I.avatar_url + '?thumbnail&size=64' }, onclick={ set-avatar }, alt='avatar', data-user-preview={ I.id }) - a.name(href={ CONFIG.url + '/' + I.username }) { I.name } - p.username @{ I.username } - -style. - display block - background #fff - - > .banner - height 100px - background-color #f5f5f5 - background-size cover - background-position center - - > .avatar - display block - position absolute - top 76px - left 16px - width 58px - height 58px - margin 0 - border solid 3px #fff - border-radius 8px - vertical-align bottom - - > .name - display block - margin 10px 0 0 92px - line-height 16px - font-weight bold - color #555 - - > .username - display block - margin 4px 0 8px 92px - line-height 16px - font-size 0.9em - color #999 - -script. - @mixin \i - @mixin \user-preview - @mixin \update-avatar - @mixin \update-banner - - @set-avatar = ~> - @update-avatar @I, (i) ~> - @update-i i - - @set-banner = ~> - @update-banner @I, (i) ~> - @update-i i +<mk-profile-home-widget> + <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> + <p class="username">@{ I.username }</p> + <style type="stylus"> + :scope + display block + background #fff + + > .banner + height 100px + background-color #f5f5f5 + background-size cover + background-position center + + > .avatar + display block + position absolute + top 76px + left 16px + width 58px + height 58px + margin 0 + border solid 3px #fff + border-radius 8px + vertical-align bottom + + > .name + display block + margin 10px 0 0 92px + line-height 16px + font-weight bold + color #555 + + > .username + display block + margin 4px 0 8px 92px + line-height 16px + font-size 0.9em + color #999 + + </style> + <script> + @mixin \i + @mixin \user-preview + @mixin \update-avatar + @mixin \update-banner + + @set-avatar = ~> + @update-avatar @I, (i) ~> + @update-i i + + @set-banner = ~> + @update-banner @I, (i) ~> + @update-i i + </script> +</mk-profile-home-widget> diff --git a/src/web/app/desktop/tags/home-widgets/rss-reader.tag b/src/web/app/desktop/tags/home-widgets/rss-reader.tag index b9095fb2d21bb76307b4b2019b2e706f910a2f72..bfd9d32e52a9703d8bda09c4318acb912e560fb0 100644 --- a/src/web/app/desktop/tags/home-widgets/rss-reader.tag +++ b/src/web/app/desktop/tags/home-widgets/rss-reader.tag @@ -1,94 +1,94 @@ -mk-rss-reader-home-widget - p.title - i.fa.fa-rss-square - | RSS - button(onclick={ settings }, title='è¨å®š'): i.fa.fa-cog - div.feed(if={ !initializing }) - virtual(each={ item in items }) - a(href={ item.link }, target='_blank') { item.title } - p.initializing(if={ initializing }) - 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 - 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 +<mk-rss-reader-home-widget> + <p class="title"><i class="fa fa-rss-square"></i>RSS</p> + <button onclick="{ settings }" title="è¨å®š"><i class="fa fa-cog"></i></button> + <div class="feed" if="{ !initializing }"> + <virtual each="{ item in items }"><a href="{ item.link }" target="_blank">{ item.title }</a></virtual> + </div> + <p class="initializing" if="{ initializing }"><i class="fa fa-spinner fa-pulse fa-fw"></i>èªã¿è¾¼ã‚“ã§ã„ã¾ã™ + <mk-ellipsis></mk-ellipsis> + </p> + <style type="stylus"> + :scope display block - padding 4px 0 - color #666 - border-bottom dashed 1px #eee - - &:last-child - border-bottom none - - > .initializing - margin 0 - padding 16px - text-align center - color #aaa - - > i - margin-right 4px - -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! + 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 + padding 4px 0 + color #666 + border-bottom dashed 1px #eee + + &:last-child + border-bottom none + + > .initializing + 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> diff --git a/src/web/app/desktop/tags/home-widgets/timeline.tag b/src/web/app/desktop/tags/home-widgets/timeline.tag index ea2746d1edec16c0400b829615043fd1cf7b0b02..2bd9d104da20d0eeffe517af15461ec734d0d521 100644 --- a/src/web/app/desktop/tags/home-widgets/timeline.tag +++ b/src/web/app/desktop/tags/home-widgets/timeline.tag @@ -1,113 +1,111 @@ -mk-timeline-home-widget - mk-following-setuper(if={ no-following }) - div.loading(if={ is-loading }) - mk-ellipsis-icon - p.empty(if={ is-empty }) - i.fa.fa-comments-o - | 自分ã®æŠ•ç¨¿ã‚„ã€è‡ªåˆ†ãŒãƒ•ã‚©ãƒãƒ¼ã—ã¦ã„るユーザーã®æŠ•ç¨¿ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚ - 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 - - > 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 +<mk-timeline-home-widget> + <mk-following-setuper if="{ noFollowing }"></mk-following-setuper> + <div class="loading" if="{ isLoading }"> + <mk-ellipsis-icon></mk-ellipsis-icon> + </div> + <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> + <style type="stylus"> + :scope display block - margin-bottom 16px - font-size 3em - color #ccc - -script. - @mixin \i - @mixin \api - @mixin \stream - - @is-loading = true - @is-empty = false - @more-loading = false - @no-following = @I.following_count == 0 - - @on \mount ~> - @stream.on \post @on-stream-post - @stream.on \follow @on-stream-follow - @stream.on \unfollow @on-stream-unfollow - - document.add-event-listener \keydown @on-document-keydown - window.add-event-listener \scroll @on-scroll - - @load ~> - @trigger \loaded - - @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 + 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 + margin-bottom 16px + font-size 3em + color #ccc + + </style> + <script> + @mixin \i + @mixin \api + @mixin \stream + + @is-loading = true + @is-empty = false + @more-loading = false + @no-following = @I.following_count == 0 + + @on \mount ~> + @stream.on \post @on-stream-post + @stream.on \follow @on-stream-follow + @stream.on \unfollow @on-stream-unfollow + + document.add-event-listener \keydown @on-document-keydown + window.add-event-listener \scroll @on-scroll + + @load ~> + @trigger \loaded + + @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! - @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 + @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.prepend-posts posts - .catch (err) ~> - console.error err - - @on-stream-post = (post) ~> - @is-empty = false - @update! - @refs.timeline.add-post post + @refs.timeline.add-post post - @on-stream-follow = ~> - @load! + @on-stream-follow = ~> + @load! - @on-stream-unfollow = ~> - @load! + @on-stream-unfollow = ~> + @load! - @on-scroll = ~> - current = window.scroll-y + window.inner-height - if current > document.body.offset-height - 8 - @more! + @on-scroll = ~> + current = window.scroll-y + window.inner-height + if current > document.body.offset-height - 8 + @more! + </script> +</mk-timeline-home-widget> diff --git a/src/web/app/desktop/tags/home-widgets/tips.tag b/src/web/app/desktop/tags/home-widgets/tips.tag index 9c1aa33ec07058dece329080ed076648c5964fce..d85da0d2956fb2b48170c1be79d983aaa5e80f85 100644 --- a/src/web/app/desktop/tags/home-widgets/tips.tag +++ b/src/web/app/desktop/tags/home-widgets/tips.tag @@ -1,70 +1,71 @@ -mk-tips-home-widget - p@tip - i.fa.fa-lightbulb-o - span@text +<mk-tips-home-widget> + <p ref="tip"><i class="fa fa-lightbulb-o"></i><span ref="text"></span></p> + <style type="stylus"> + :scope + display block + background transparent !important + border none !important + overflow visible !important -style. - display block - background transparent !important - border none !important - overflow visible !important + > p + display block + margin 0 + padding 0 12px + text-align center + font-size 0.7em + color #999 - > p - display block - margin 0 - padding 0 12px - text-align center - font-size 0.7em - color #999 + > i + margin-right 4px - > i - margin-right 4px + kbd + display inline + padding 0 6px + margin 0 2px + font-size 1em + font-family inherit + border solid 1px #999 + border-radius 2px - kbd - display inline - padding 0 6px - margin 0 2px - font-size 1em - font-family inherit - border solid 1px #999 - border-radius 2px + </style> + <script> + @tips = [ + '<kbd>t</kbd>ã§ã‚¿ã‚¤ãƒ ラインã«ãƒ•ã‚©ãƒ¼ã‚«ã‚¹ã§ãã¾ã™' + '<kbd>p</kbd>ã¾ãŸã¯<kbd>n</kbd>ã§æŠ•ç¨¿ãƒ•ã‚©ãƒ¼ãƒ ã‚’é–‹ãã¾ã™' + '投稿フォームã«ã¯ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグ&ドãƒãƒƒãƒ—ã§ãã¾ã™' + '投稿フォームã«ã‚¯ãƒªãƒƒãƒ—ボードã«ã‚ã‚‹ç”»åƒãƒ‡ãƒ¼ã‚¿ã‚’ペーストã§ãã¾ã™' + 'ドライブã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグ&ドãƒãƒƒãƒ—ã—ã¦ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰ã§ãã¾ã™' + 'ドライブã§ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグã—ã¦ãƒ•ã‚©ãƒ«ãƒ€ç§»å‹•ã§ãã¾ã™' + 'ドライブã§ãƒ•ã‚©ãƒ«ãƒ€ã‚’ドラッグã—ã¦ãƒ•ã‚©ãƒ«ãƒ€ç§»å‹•ã§ãã¾ã™' + 'ホームをカスタマイズã§ãã¾ã™(準備ä¸)' + 'Misskeyã¯MIT Licenseã§ã™' + ] -script. - @tips = [ - '<kbd>t</kbd>ã§ã‚¿ã‚¤ãƒ ラインã«ãƒ•ã‚©ãƒ¼ã‚«ã‚¹ã§ãã¾ã™' - '<kbd>p</kbd>ã¾ãŸã¯<kbd>n</kbd>ã§æŠ•ç¨¿ãƒ•ã‚©ãƒ¼ãƒ ã‚’é–‹ãã¾ã™' - '投稿フォームã«ã¯ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグ&ドãƒãƒƒãƒ—ã§ãã¾ã™' - '投稿フォームã«ã‚¯ãƒªãƒƒãƒ—ボードã«ã‚ã‚‹ç”»åƒãƒ‡ãƒ¼ã‚¿ã‚’ペーストã§ãã¾ã™' - 'ドライブã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグ&ドãƒãƒƒãƒ—ã—ã¦ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰ã§ãã¾ã™' - 'ドライブã§ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグã—ã¦ãƒ•ã‚©ãƒ«ãƒ€ç§»å‹•ã§ãã¾ã™' - 'ドライブã§ãƒ•ã‚©ãƒ«ãƒ€ã‚’ドラッグã—ã¦ãƒ•ã‚©ãƒ«ãƒ€ç§»å‹•ã§ãã¾ã™' - 'ホームをカスタマイズã§ãã¾ã™(準備ä¸)' - 'Misskeyã¯MIT Licenseã§ã™' - ] + @on \mount ~> + @set! + @clock = set-interval @change, 20000ms - @on \mount ~> - @set! - @clock = set-interval @change, 20000ms + @on \unmount ~> + clear-interval @clock - @on \unmount ~> - clear-interval @clock + @set = ~> + @refs.text.innerHTML = @tips[Math.floor Math.random! * @tips.length] + @update! - @set = ~> - @refs.text.innerHTML = @tips[Math.floor Math.random! * @tips.length] - @update! + @change = ~> + Velocity @refs.tip, { + opacity: 0 + } { + duration: 500ms + easing: \linear + complete: @set + } - @change = ~> - Velocity @refs.tip, { - opacity: 0 - } { - duration: 500ms - easing: \linear - complete: @set - } - - Velocity @refs.tip, { - opacity: 1 - } { - duration: 500ms - easing: \linear - } + Velocity @refs.tip, { + opacity: 1 + } { + duration: 500ms + easing: \linear + } + </script> +</mk-tips-home-widget> diff --git a/src/web/app/desktop/tags/home-widgets/user-recommendation.tag b/src/web/app/desktop/tags/home-widgets/user-recommendation.tag index bfb90da0655c44a82b1db6faec10edc3b7654706..bcf770ddab56f8f0361bbaa86e0105b1bf7fbf25 100644 --- a/src/web/app/desktop/tags/home-widgets/user-recommendation.tag +++ b/src/web/app/desktop/tags/home-widgets/user-recommendation.tag @@ -1,154 +1,152 @@ -mk-user-recommendation-home-widget - p.title - i.fa.fa-users - | ãŠã™ã™ã‚ユーザー - button(onclick={ refresh }, title='他を見る'): i.fa.fa-refresh - div.user(if={ !loading && users.length != 0 }, each={ _user in users }) - a.avatar-anchor(href={ CONFIG.url + '/' + _user.username }) - img.avatar(src={ _user.avatar_url + '?thumbnail&size=42' }, alt='', data-user-preview={ _user.id }) - div.body - a.name(href={ CONFIG.url + '/' + _user.username }, data-user-preview={ _user.id }) { _user.name } - p.username @{ _user.username } - mk-follow-button(user={ _user }) - p.empty(if={ !loading && users.length == 0 }) - | ã„ã¾ã›ã‚“ï¼ - p.loading(if={ loading }) - 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 "" +<mk-user-recommendation-home-widget> + <p class="title"><i class="fa fa-users"></i>ãŠã™ã™ã‚ユーザー</p> + <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> + <div class="body"><a class="name" href="{ CONFIG.url + '/' + _user.username }" data-user-preview="{ _user.id }">{ _user.name }</a> + <p class="username">@{ _user.username }</p> + </div> + <mk-follow-button user="{ _user }"></mk-follow-button> + </div> + <p class="empty" if="{ !loading && users.length == 0 }">ã„ã¾ã›ã‚“ï¼</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 - clear both + background #fff - > .avatar-anchor - display block - float left - margin 0 12px 0 0 - - > .avatar - display block - width 42px - height 42px + > .title margin 0 - border-radius 8px - vertical-align bottom - - > .body - float left - width calc(100% - 54px) + 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 - > .name + &:hover + color #aaa + + &:active + color #999 + + > .user + padding 16px + border-bottom solid 1px #eee + + &:last-child + border-bottom none + + &:after + content "" + display block + 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 + display block + margin 0 + font-size 15px + line-height 16px + color #ccc + + > mk-follow-button + position absolute + top 16px + right 16px + + > .empty margin 0 - font-size 16px - line-height 24px - color #555 + padding 16px + text-align center + color #aaa - > .username - display block + > .loading 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 + padding 16px + text-align center + color #aaa - > .loading - margin 0 - padding 16px - text-align center - color #aaa + > i + margin-right 4px - > i - margin-right 4px + </style> + <script> + @mixin \api + @mixin \user-preview -script. - @mixin \api - @mixin \user-preview - - @users = null - @loading = true - - @limit = 3users - @page = 0 + @users = null + @loading = true - @on \mount ~> - @fetch! - @clock = set-interval ~> + @limit = 3users + @page = 0 + + @on \mount ~> + @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 - @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! + @page = 0 + else + @page++ + @fetch! + </script> +</mk-user-recommendation-home-widget> diff --git a/src/web/app/desktop/tags/home.tag b/src/web/app/desktop/tags/home.tag index 1ae856a6b278cd3b10a2d025db4bf168c9e0cd85..6d4a308ac2986c24e45851dd285fd74f1df69f54 100644 --- a/src/web/app/desktop/tags/home.tag +++ b/src/web/app/desktop/tags/home.tag @@ -1,86 +1,91 @@ -mk-home - div.main - div.left@left - main - mk-timeline-home-widget@tl(if={ mode == 'timeline' }) - mk-mentions-home-widget@tl(if={ mode == 'mentions' }) - div.right@right - mk-detect-slow-internet-connection-notice - -style. - display block - - > .main - margin 0 auto - max-width 1200px - - &:after - content "" +<mk-home> + <div class="main"> + <div class="left" ref="left"></div> + <main> + <mk-timeline-home-widget ref="tl" if="{ mode == 'timeline' }"></mk-timeline-home-widget> + <mk-mentions-home-widget ref="tl" if="{ mode == 'mentions' }"></mk-mentions-home-widget> + </main> + <div class="right" ref="right"></div> + </div> + <mk-detect-slow-internet-connection-notice></mk-detect-slow-internet-connection-notice> + <style type="stylus"> + :scope display block - clear both - > * - 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 + > .main margin 0 auto - -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! + max-width 1200px + + &:after + content "" + display block + clear both + + > * + 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 + + </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> diff --git a/src/web/app/desktop/tags/image-dialog.tag b/src/web/app/desktop/tags/image-dialog.tag index 6a3885d7c7c5dd0af77aa58daea514f349b37f60..41ec876621cff7bcfea359f1a51da60cf2866579 100644 --- a/src/web/app/desktop/tags/image-dialog.tag +++ b/src/web/app/desktop/tags/image-dialog.tag @@ -1,73 +1,75 @@ -mk-image-dialog - div.bg@bg(onclick={ close }) - img@img(src={ image.url }, alt={ image.name }, title={ image.name }, onclick={ close }) +<mk-image-dialog> + <div class="bg" ref="bg" onclick="{ close }"></div><img ref="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. - display block - position fixed - z-index 2048 - top 0 - left 0 - width 100% - height 100% - opacity 0 + > .bg + display block + position fixed + z-index 1 + top 0 + left 0 + width 100% + height 100% + background rgba(0, 0, 0, 0.7) - > .bg - display block - position fixed - z-index 1 - top 0 - left 0 - width 100% - height 100% - background rgba(0, 0, 0, 0.7) + > img + position fixed + z-index 2 + top 0 + right 0 + bottom 0 + left 0 + max-width 100% + max-height 100% + margin auto + cursor zoom-out - > img - position fixed - z-index 2 - top 0 - right 0 - bottom 0 - left 0 - max-width 100% - max-height 100% - margin auto - cursor zoom-out + </style> + <script> + @image = @opts.image -script. - @image = @opts.image + @on \mount ~> + Velocity @root, { + opacity: 1 + } { + duration: 100ms + easing: \linear + } - @on \mount ~> - Velocity @root, { - opacity: 1 - } { - duration: 100ms - easing: \linear - } + #Velocity @img, { + # scale: 1 + # opacity: 1 + #} { + # duration: 200ms + # easing: \ease-out + #} - #Velocity @img, { - # scale: 1 - # opacity: 1 - #} { - # duration: 200ms - # easing: \ease-out - #} + @close = ~> + Velocity @root, { + opacity: 0 + } { + duration: 100ms + easing: \linear + complete: ~> @unmount! + } - @close = ~> - Velocity @root, { - opacity: 0 - } { - duration: 100ms - easing: \linear - complete: ~> @unmount! - } - - #Velocity @img, { - # scale: 0.9 - # opacity: 0 - #} { - # duration: 200ms - # easing: \ease-in - # complete: ~> - # @unmount! - #} + #Velocity @img, { + # scale: 0.9 + # opacity: 0 + #} { + # duration: 200ms + # easing: \ease-in + # complete: ~> + # @unmount! + #} + </script> +</mk-image-dialog> diff --git a/src/web/app/desktop/tags/images-viewer.tag b/src/web/app/desktop/tags/images-viewer.tag index a9939d67c44cb1cf655a977f600c3ca192726acb..c08c8d69266c7d7ef68b0763fde906d137da20ff 100644 --- a/src/web/app/desktop/tags/images-viewer.tag +++ b/src/web/app/desktop/tags/images-viewer.tag @@ -1,43 +1,45 @@ -mk-images-viewer - div.image@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 }) - -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 +<mk-images-viewer> + <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> + <style type="stylus"> + :scope display block - max-height 256px - max-width 100% - margin 0 auto - - &:hover - > img - visibility hidden - - &:not(:hover) - background-image none !important - -script. - @images = @opts.images - @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 + 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 + max-height 256px + max-width 100% + margin 0 auto + + &:hover + > img + visibility hidden + + &:not(:hover) + background-image none !important + + </style> + <script> + @images = @opts.images + @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> diff --git a/src/web/app/desktop/tags/input-dialog.tag b/src/web/app/desktop/tags/input-dialog.tag index 62ec4f5177a99b1ec0c8310333365932a0a685c6..a71ee5862383715e82ea21aae6e2268b14c282f9 100644 --- a/src/web/app/desktop/tags/input-dialog.tag +++ b/src/web/app/desktop/tags/input-dialog.tag @@ -1,156 +1,157 @@ -mk-input-dialog - mk-window@window(is-modal={ true }, width={ '500px' }) - <yield to="header"> - i.fa.fa-i-cursor - | { parent.title } - </yield> - <yield to="content"> - div.body - input@text(oninput={ parent.update }, onkeydown={ parent.on-keydown }, placeholder={ parent.placeholder }) - div.action - button.cancel(onclick={ parent.cancel }) ã‚ャンセル - button.ok(disabled={ !parent.allow-empty && refs.text.value.length == 0 }, onclick={ parent.ok }) 決定 - </yield> - -style. - display block - - > mk-window - [data-yield='header'] - > i - margin-right 4px - - [data-yield='content'] - > .body - padding 16px - - > input - display block - 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 - - &: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 - - &::-webkit-input-placeholder - color rgba($theme-color, 0.3) - - > .action - height 72px - background lighten($theme-color, 95%) - - .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 +<mk-input-dialog> + <mk-window ref="window" is-modal="{ true }" width="{ '500px' }"><yield to="header"><i class="fa fa-i-cursor"></i>{ parent.title }</yield> +<yield to="content"> + <div class="body"> + <input ref="text" oninput="{ parent.update }" onkeydown="{ parent.onKeydown }" placeholder="{ parent.placeholder }"/> + </div> + <div class="action"> + <button class="cancel" onclick="{ parent.cancel }">ã‚ャンセル</button> + <button class="ok" disabled="{ !parent.allowEmpty && refs.text.value.length == 0 }" onclick="{ parent.ok }">決定</button> + </div></yield> + </mk-window> + <style type="stylus"> + :scope + display block + + > mk-window + [data-yield='header'] + > i + margin-right 4px + + [data-yield='content'] + > .body + padding 16px + + > input + display block + 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 + + &: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 + + &::-webkit-input-placeholder + color rgba($theme-color, 0.3) + + > .action + height 72px + background lighten($theme-color, 95%) + + .ok + .cancel + display block 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 - - .ok - 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%) - - &: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 - - .cancel - right 148px - color #888 - background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) - border solid 1px #e2e2e2 - - &:hover - background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) - border-color #dcdcdc - - &:active - background #ececec - border-color #dcdcdc - -script. - @done = false - - @title = @opts.title - @placeholder = @opts.placeholder - @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 = ~> + 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 + cursor default + + .ok + 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%) + + &: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 + + .cancel + right 148px + color #888 + background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) + border solid 1px #e2e2e2 + + &:hover + background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) + border-color #dcdcdc + + &:active + background #ececec + border-color #dcdcdc + + </style> + <script> @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! + + @title = @opts.title + @placeholder = @opts.placeholder + @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 + @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> diff --git a/src/web/app/desktop/tags/list-user.tag b/src/web/app/desktop/tags/list-user.tag index 1058de22e00a1e1277e5e7bbdb037473dc35eaae..ecf1e04d2e520f355dea2b5506836184ff72bacc 100644 --- a/src/web/app/desktop/tags/list-user.tag +++ b/src/web/app/desktop/tags/list-user.tag @@ -1,100 +1,98 @@ -mk-list-user - a.avatar-anchor(href={ CONFIG.url + '/' + user.username }) - img.avatar(src={ user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.main - header - div.left - a.name(href={ CONFIG.url + '/' + user.username }) - | { user.name } - span.username - | @{ user.username } - div.body - p.followed(if={ user.is_followed }) フォãƒãƒ¼ã•ã‚Œã¦ã„ã¾ã™ - div.bio { user.bio } - 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 +<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> + <div class="main"> + <header> + <div class="left"><a class="name" href="{ CONFIG.url + '/' + user.username }">{ user.name }</a><span class="username">@{ user.username }</span></div> + </header> + <div class="body"> + <p class="followed" if="{ user.is_followed }">フォãƒãƒ¼ã•ã‚Œã¦ã„ã¾ã™</p> + <div class="bio">{ user.bio }</div> + </div> + </div> + <mk-follow-button user="{ user }"></mk-follow-button> + <style type="stylus"> + :scope display block - width 58px - height 58px margin 0 - border-radius 8px - vertical-align bottom - - > .main - float left - width calc(100% - 74px) - - > header - margin-bottom 2px - white-space nowrap + padding 16px + font-size 16px &:after content "" display block clear both - > .left + > .avatar-anchor + display block float left + margin 0 16px 0 0 - > .name - display inline + > .avatar + display block + width 58px + height 58px margin 0 - padding 0 - color #777 - font-size 1em - font-weight 700 - text-align left - text-decoration none + border-radius 8px + vertical-align bottom - &:hover - text-decoration underline + > .main + float left + width calc(100% - 74px) - > .username - text-align left - margin 0 0 0 8px - color #ccc + > header + margin-bottom 2px + white-space nowrap - > .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 + &:after + content "" + display block + clear both - > .bio - cursor default - display block - margin 0 - padding 0 - word-wrap break-word - font-size 1.1em - color #717171 + > .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 + > mk-follow-button + position absolute + top 16px + right 16px -script. - @user = @opts.user + </style> + <script>@user = @opts.user</script> +</mk-list-user> diff --git a/src/web/app/desktop/tags/messaging/form.tag b/src/web/app/desktop/tags/messaging/form.tag index 12eb0cb40fd5eed37ac7abb87fd85af3cabf0fba..b521eb2fd3e9ab21f7485543de7683fa6ce7d713 100644 --- a/src/web/app/desktop/tags/messaging/form.tag +++ b/src/web/app/desktop/tags/messaging/form.tag @@ -1,162 +1,161 @@ -mk-messaging-form - textarea@text(onkeypress={ onkeypress }, onpaste={ onpaste }, placeholder='ã“ã“ã«ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’入力') - div.files - mk-uploader@uploader - button.send(onclick={ send }, disabled={ sending }, title='メッセージをé€ä¿¡') - i.fa.fa-paper-plane(if={ !sending }) - i.fa.fa-spinner.fa-spin(if={ sending }) - button.attach-from-local(type='button', title='PCã‹ã‚‰ç”»åƒã‚’添付ã™ã‚‹') - i.fa.fa-upload - button.attach-from-drive(type='button', title='アルãƒãƒ ã‹ã‚‰ç”»åƒã‚’添付ã™ã‚‹') - 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 '' +<mk-messaging-form> + <textarea ref="text" onkeypress="{ onkeypress }" onpaste="{ onpaste }" placeholder="ã“ã“ã«ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’入力"></textarea> + <div class="files"></div> + <mk-uploader ref="uploader"></mk-uploader> + <button class="send" onclick="{ send }" disabled="{ sending }" title="メッセージをé€ä¿¡"><i class="fa fa-paper-plane" if="{ !sending }"></i><i class="fa fa-spinner fa-spin" if="{ sending }"></i></button> + <button class="attach-from-local" type="button" title="PCã‹ã‚‰ç”»åƒã‚’添付ã™ã‚‹"><i class="fa fa-upload"></i></button> + <button class="attach-from-drive" type="button" title="アルãƒãƒ ã‹ã‚‰ç”»åƒã‚’添付ã™ã‚‹"><i class="fa fa-folder-open"></i></button> + <input name="file" type="file" accept="image/*"/> + <style type="stylus"> + :scope display block - clear both - > 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 - - &:hover - > .remove - display block - - > .remove - display none - position absolute - right -6px - top -6px + > textarea + cursor auto + display block + width 100% + min-width 100% + max-width 100% + height 64px margin 0 - padding 0 - background transparent + padding 8px + font-size 1em + color #000 outline none border none + border-top solid 1px #eee border-radius 0 box-shadow none - cursor pointer - - .attach-from-local - .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 - - &:hover - color $theme-color - - &:active - color darken($theme-color, 10%) - transition color 0s ease - - input[type=file] - display none - -script. - @mixin \api - - @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! + 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 - @clear = ~> - @refs.text.value = '' - @files = [] - @update! + &: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 + clear both + + > 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 + + &:hover + > .remove + display block + + > .remove + display none + position absolute + right -6px + top -6px + margin 0 + padding 0 + background transparent + outline none + border none + border-radius 0 + box-shadow none + cursor pointer + + .attach-from-local + .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 + + &:hover + color $theme-color + + &:active + color darken($theme-color, 10%) + transition color 0s ease + + input[type=file] + display none + + </style> + <script> + @mixin \api + + @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! + </script> +</mk-messaging-form> diff --git a/src/web/app/desktop/tags/messaging/index.tag b/src/web/app/desktop/tags/messaging/index.tag index 9f57500b831448cd096d7b2d6732ed01affad2b2..eeb92fc3f086d4548a56eb1934448828817f854e 100644 --- a/src/web/app/desktop/tags/messaging/index.tag +++ b/src/web/app/desktop/tags/messaging/index.tag @@ -1,302 +1,301 @@ -mk-messaging - div.search - div.form - label(for='search-input') - i.fa.fa-search - input@search-input(type='search', oninput={ search }, placeholder='ユーザーを探ã™') - div.result - ol.users(if={ search-result.length > 0 }) - li(each={ user in search-result }) - a(onclick={ user._click }) - img.avatar(src={ user.avatar_url + '?thumbnail&size=32' }, alt='') - span.name { user.name } - span.username @{ user.username } - div.main - div.history(if={ history.length > 0 }) - virtual(each={ history }) - a.user(data-is-me={ is_me }, data-is-read={ is_read }, onclick={ _click }): div - img.avatar(src={ (is_me ? recipient.avatar_url : user.avatar_url) + '?thumbnail&size=64' }, alt='') - header - span.name { is_me ? recipient.name : user.name } - span.username { '@' + (is_me ? recipient.username : user.username ) } - mk-time(time={ created_at }) - div.body - p.text - span.me(if={ is_me }) ã‚ãªãŸ: - | { text } - p.no-history(if={ history.length == 0 }) - | å±¥æ´ã¯ã‚ã‚Šã¾ã›ã‚“。 - br - | ユーザーを検索ã—ã¦ã€ã„ã¤ã§ã‚‚メッセージをé€å—ä¿¡ã§ãã¾ã™ã€‚ - -style. - 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 +<mk-messaging> + <div class="search"> + <div class="form"> + <label for="search-input"><i class="fa fa-search"></i></label> + <input ref="searchInput" type="search" oninput="{ search }" placeholder="ユーザーを探ã™"/> + </div> + <div class="result"> + <ol class="users" if="{ searchResult.length > 0 }"> + <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> + </ol> + </div> + </div> + <div class="main"> + <div class="history" if="{ history.length > 0 }"> + <virtual each="{ history }"><a class="user" data-is-me="{ is_me }" data-is-read="{ is_read }" onclick="{ _click }"> + <div><img class="avatar" src="{ (is_me ? recipient.avatar_url : user.avatar_url) + '?thumbnail&size=64' }" alt=""/> + <header><span class="name">{ is_me ? recipient.name : user.name }</span><span class="username">{ '@' + (is_me ? recipient.username : user.username ) }</span> + <mk-time time="{ created_at }"></mk-time> + </header> + <div class="body"> + <p class="text"><span class="me" if="{ is_me }">ã‚ãªãŸ:</span>{ text }</p> + </div> + </div></a></virtual> + </div> + <p class="no-history" if="{ history.length == 0 }">å±¥æ´ã¯ã‚ã‚Šã¾ã›ã‚“。<br/>ユーザーを検索ã—ã¦ã€ã„ã¤ã§ã‚‚メッセージをé€å—ä¿¡ã§ãã¾ã™ã€‚</p> + </div> + <style type="stylus"> + :scope + display block + + > .search display block position absolute top 0 - left 8px + left 0 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% - 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 + background #fff + box-shadow 0 0px 2px rgba(0, 0, 0, 0.2) - > .history + > .form + padding 8px + background #f7f7f7 - > a - display block - padding 20px 30px - text-decoration none - background #fff - border-bottom solid 1px #eee + > label + display block + position absolute + top 0 + left 8px + z-index 1 + height 100% + width 38px + pointer-events none - * - pointer-events none - user-select 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% + 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 - background #fafafa + &:hover + border solid 1px #ddd + transition border 0.2s ease - > .avatar - filter saturate(200%) + &:focus + color darken($theme-color, 20%) + border solid 1px $theme-color + transition color 0, border 0 - &:active - background #eee + > .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 - &[data-is-read] - &[data-is-me] - opacity 0.8 + > a + display block + padding 20px 30px + text-decoration none + background #fff + border-bottom solid 1px #eee - &:not([data-is-me]):not([data-is-read]) - background-image url("/_/resources/desktop/unread.svg") - background-repeat no-repeat - background-position 0 center + * + pointer-events none + user-select none - &: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 - top 0 - right 0 - display inline - color rgba(0, 0, 0, 0.5) - font-size small + &:hover + background #fafafa - > .avatar - float left - width 54px - height 54px - margin 0 16px 0 0 - border-radius 8px - transition all 0.1s ease + > .avatar + filter saturate(200%) - > .body + &:active + background #eee - > .text - display block - margin 0 0 0 0 - padding 0 - overflow hidden - word-wrap break-word - font-size 1.1em - color rgba(0, 0, 0, 0.8) + &[data-is-read] + &[data-is-me] + opacity 0.8 - .me - color rgba(0, 0, 0, 0.4) + &:not([data-is-me]):not([data-is-read]) + background-image url("/_/resources/desktop/unread.svg") + background-repeat no-repeat + background-position 0 center - > .image + &:after + content "" display block - max-width 100% - max-height 512px - - > .no-history - margin 0 - padding 2em 1em - text-align center - color #999 - font-weight 500 - -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! - .catch (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 + 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 + top 0 + right 0 + display inline + color rgba(0, 0, 0, 0.5) + font-size small + + > .avatar + float left + width 54px + height 54px + margin 0 16px 0 0 + border-radius 8px + transition all 0.1s ease + + > .body + + > .text + display block + margin 0 0 0 0 + padding 0 + overflow hidden + word-wrap break-word + font-size 1.1em + color rgba(0, 0, 0, 0.8) + + .me + 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! .catch (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> diff --git a/src/web/app/desktop/tags/messaging/message.tag b/src/web/app/desktop/tags/messaging/message.tag index d7a2cc32a6a43f402fc0e99f382dce845879f772..517689d132d3e47fddc81290aef37a250b2aeeec 100644 --- a/src/web/app/desktop/tags/messaging/message.tag +++ b/src/web/app/desktop/tags/messaging/message.tag @@ -1,227 +1,230 @@ -mk-messaging-message(data-is-me={ message.is_me }) - a.avatar-anchor(href={ CONFIG.url + '/' + message.user.username }, title={ message.user.username }, target='_blank') - img.avatar(src={ message.user.avatar_url + '?thumbnail&size=64' }, alt='') - div.content-container - div.balloon - p.read(if={ message.is_me && message.is_read }) æ—¢èª - button.delete-button(if={ message.is_me }, title='メッセージを削除') - img(src='/_/resources/desktop/messaging/delete.png', alt='Delete') - div.content(if={ !message.is_deleted }) - div@text - div.image(if={ message.file }) - img(src={ message.file.url }, alt='image', title={ message.file.name }) - div.content(if={ message.is_deleted }) - p.is-deleted ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯å‰Šé™¤ã•ã‚Œã¾ã—㟠- footer - mk-time(time={ message.created_at }) - i.fa.fa-pencil.is-edited(if={ message.is_edited }) - -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 - min-width 54px - min-height 54px - max-width 54px - max-height 54px - margin 0 - border-radius 8px - transition all 0.1s ease - - > .content-container - display block - margin 0 12px - padding 0 - max-width calc(100% - 78px) - - > .balloon +<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> + <div class="content-container"> + <div class="balloon"> + <p class="read" if="{ message.is_me && message.is_read }">æ—¢èª</p> + <button class="delete-button" if="{ message.is_me }" title="メッセージを削除"><img src="/_/resources/desktop/messaging/delete.png" alt="Delete"/></button> + <div class="content" if="{ !message.is_deleted }"> + <div ref="text"></div> + <div class="image" if="{ message.file }"><img src="{ message.file.url }" alt="image" title="{ message.file.name }"/></div> + </div> + <div class="content" if="{ message.is_deleted }"> + <p class="is-deleted">ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸ</p> + </div> + </div> + <footer> + <mk-time time="{ message.created_at }"></mk-time><i class="fa fa-pencil is-edited" if="{ message.is_edited }"></i> + </footer> + </div> + <style type="stylus"> + :scope + $me-balloon-color = #23A7B6 + display block - float inherit - margin 0 - padding 0 - max-width 100% - min-height 38px - border-radius 16px - - &:before + padding 10px 12px 10px 12px + background-color transparent + + &:after content "" - pointer-events none display block - position absolute - top 12px + clear both - &:hover - > .delete-button - display block - - > .delete-button - display none - position absolute - z-index 1 - top -4px - right -4px - margin 0 - padding 0 - cursor pointer - outline none - border none - border-radius 0 - box-shadow none - background transparent - - > img - vertical-align bottom - width 16px - height 16px - cursor pointer - - > .read - user-select none + > .avatar-anchor 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 + > .avatar display block + min-width 54px + min-height 54px + max-width 54px + max-height 54px margin 0 - padding 0 - overflow hidden - word-wrap break-word - font-size 1em - color rgba(0, 0, 0, 0.5) + border-radius 8px + transition all 0.1s ease - > [ref='text'] + > .content-container + display block + margin 0 12px + padding 0 + max-width calc(100% - 78px) + + > .balloon display block + float inherit margin 0 - padding 8px 16px - overflow hidden - word-wrap break-word - font-size 1em - color rgba(0, 0, 0, 0.8) - - &, * - user-select text - cursor auto - - & + .file - &.image - > img - border-radius 0 0 16px 16px - - > .file - &.image - > img + padding 0 + max-width 100% + min-height 38px + border-radius 16px + + &:before + content "" + pointer-events none + display block + position absolute + top 12px + + &:hover + > .delete-button display block - max-width 100% - max-height 512px - border-radius 16px - - > footer - display block - clear both - margin 0 - padding 2px - font-size 10px - color rgba(0, 0, 0, 0.4) - - > .is-edited - margin-left 4px - - &:not([data-is-me='true']) - > .avatar-anchor - float left - - > .content-container - float left - - > .balloon - background #eee - - &:before - left -14px - border-top solid 8px transparent - border-right solid 8px #eee - border-bottom solid 8px transparent - border-left solid 8px transparent - > footer - text-align left + > .delete-button + display none + position absolute + z-index 1 + top -4px + right -4px + margin 0 + padding 0 + cursor pointer + outline none + border none + border-radius 0 + box-shadow none + background transparent - &[data-is-me='true'] - > .avatar-anchor - float right - - > .content-container - float right - - > .balloon - background $me-balloon-color - - &: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 - - > .content - - > p.is-deleted - color rgba(255, 255, 255, 0.5) - - > [ref='text'] - &, * - color #fff !important - - > footer - text-align right - - &[data-is-deleted='true'] - > .content-container - opacity 0.5 - -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 + > img + 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 + margin 0 + padding 0 + overflow hidden + word-wrap break-word + font-size 1em + color rgba(0, 0, 0, 0.5) + + > [ref='text'] + display block + margin 0 + padding 8px 16px + overflow hidden + word-wrap break-word + font-size 1em + color rgba(0, 0, 0, 0.8) + + &, * + user-select text + cursor auto + + & + .file + &.image + > img + border-radius 0 0 16px 16px + + > .file + &.image + > img + display block + max-width 100% + max-height 512px + border-radius 16px + + > footer + display block + clear both + margin 0 + padding 2px + font-size 10px + color rgba(0, 0, 0, 0.4) + + > .is-edited + margin-left 4px + + &:not([data-is-me='true']) + > .avatar-anchor + float left + + > .content-container + float left + + > .balloon + background #eee + + &:before + left -14px + border-top solid 8px transparent + border-right solid 8px #eee + border-bottom solid 8px transparent + border-left solid 8px transparent + + > footer + text-align left + + &[data-is-me='true'] + > .avatar-anchor + float right + + > .content-container + float right + + > .balloon + background $me-balloon-color + + &: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 + + > .content + + > p.is-deleted + color rgba(255, 255, 255, 0.5) + + > [ref='text'] + &, * + color #fff !important + + > 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> diff --git a/src/web/app/desktop/tags/messaging/room-window.tag b/src/web/app/desktop/tags/messaging/room-window.tag index 673b11419a32f63455029a86d39b8c3ea997400b..46a2297f2a2606db938c0af2907f57b60b628623 100644 --- a/src/web/app/desktop/tags/messaging/room-window.tag +++ b/src/web/app/desktop/tags/messaging/room-window.tag @@ -1,26 +1,25 @@ -mk-messaging-room-window - mk-window@window(is-modal={ false }, width={ '500px' }, height={ '560px' }) - <yield to="header"> - i.fa.fa-comments - | メッセージ: { parent.user.name } - </yield> - <yield to="content"> - mk-messaging-room(user={ parent.user }) - </yield> +<mk-messaging-room-window> + <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="content"> + <mk-messaging-room user="{ parent.user }"></mk-messaging-room></yield> + </mk-window> + <style type="stylus"> + :scope + > mk-window + [data-yield='header'] + > i + margin-right 4px -style. - > mk-window - [data-yield='header'] - > i - margin-right 4px + [data-yield='content'] + > mk-messaging-room + height 100% - [data-yield='content'] - > mk-messaging-room - height 100% + </style> + <script> + @user = @opts.user -script. - @user = @opts.user - - @on \mount ~> - @refs.window.on \closed ~> - @unmount! + @on \mount ~> + @refs.window.on \closed ~> + @unmount! + </script> +</mk-messaging-room-window> diff --git a/src/web/app/desktop/tags/messaging/room.tag b/src/web/app/desktop/tags/messaging/room.tag index ca396d7418ccbc9ac9c91ceddef5c6620b5e5046..929e62fc3a8fb60cc67291ed5778696e15746ff9 100644 --- a/src/web/app/desktop/tags/messaging/room.tag +++ b/src/web/app/desktop/tags/messaging/room.tag @@ -1,227 +1,227 @@ -mk-messaging-room - div.stream@stream - p.initializing(if={ init }) - i.fa.fa-spinner.fa-spin - | èªã¿è¾¼ã¿ä¸ - p.empty(if={ !init && messages.length == 0 }) - i.fa.fa-info-circle - | ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¨ã¾ã 会話ã—ãŸã“ã¨ãŒã‚ã‚Šã¾ã›ã‚“ - virtual(each={ message, i in messages }) - mk-messaging-message(message={ message }) - p.date(if={ i != messages.length - 1 && message._date != messages[i + 1]._date }) - span { messages[i + 1]._datetext } - - div.typings - footer - div@notifications - div.grippie(title='ドラッグã—ã¦ãƒ•ã‚©ãƒ¼ãƒ ã®åºƒã•ã‚’調整') - 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 +<mk-messaging-room> + <div class="stream" ref="stream"> + <p class="initializing" if="{ init }"><i class="fa fa-spinner fa-spin"></i>èªã¿è¾¼ã¿ä¸</p> + <p class="empty" if="{ !init && messages.length == 0 }"><i class="fa fa-info-circle"></i>ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¨ã¾ã 会話ã—ãŸã“ã¨ãŒã‚ã‚Šã¾ã›ã‚“</p> + <virtual each="{ message, i in messages }"> + <mk-messaging-message message="{ message }"></mk-messaging-message> + <p class="date" if="{ i != messages.length - 1 && message._date != messages[i + 1]._date }"><span>{ messages[i + 1]._datetext }</span></p> + </virtual> + </div> + <div class="typings"></div> + <footer> + <div ref="notifications"></div> + <div class="grippie" title="ドラッグã—ã¦ãƒ•ã‚©ãƒ¼ãƒ ã®åºƒã•ã‚’調整"></div> + <mk-messaging-form user="{ user }"></mk-messaging-form> + </footer> + <style type="stylus"> + :scope 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 + > .stream position absolute - height 1px - width 90% - top 16px + top 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 - 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 - 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 + padding 0 + background rgba(255, 255, 255, 0.95) + background-clip content-box + + > [ref='notifications'] position absolute - top 0 - left 10px - line-height 32px - font-size 16px - - > .grippie - height 10px - margin-top -10px - background transparent - cursor ns-resize - - &:hover - //background rgba(0, 0, 0, 0.1) - - &:active - //background rgba(0, 0, 0, 0.2) - -script. - @mixin \i - @mixin \api - @mixin \messaging-stream - - @user = @opts.user - @init = true - @sending = false - @messages = [] - - @connection = new @MessagingStreamConnection @I, @user.id - - @on \mount ~> - @connection.event.on \message @on-message - @connection.event.on \read @on-read - - document.add-event-listener \visibilitychange @on-visibilitychange - - @api \messaging/messages do - user_id: @user.id - .then (messages) ~> - @init = false - @messages = messages.reverse! - @update! - @scroll-to-bottom! - .catch (err) ~> - console.error err - - @on \unmount ~> - @connection.event.off \message @on-message - @connection.event.off \read @on-read - @connection.close! - - document.remove-event-listener \visibilitychange @on-visibilitychange - - @on \update ~> - @messages.for-each (message) ~> - date = (new Date message.created_at).get-date! - 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 + 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 + top 0 + left 10px + line-height 32px + font-size 16px + + > .grippie + height 10px + margin-top -10px + background transparent + cursor ns-resize + + &:hover + //background rgba(0, 0, 0, 0.1) + + &:active + //background rgba(0, 0, 0, 0.2) + + </style> + <script> + @mixin \i + @mixin \api + @mixin \messaging-stream + + @user = @opts.user + @init = true + @sending = false + @messages = [] + + @connection = new @MessagingStreamConnection @I, @user.id + + @on \mount ~> + @connection.event.on \message @on-message + @connection.event.on \read @on-read + + document.add-event-listener \visibilitychange @on-visibilitychange + + @api \messaging/messages do + user_id: @user.id + .then (messages) ~> + @init = false + @messages = messages.reverse! @update! + @scroll-to-bottom! + .catch (err) ~> + console.error err - @is-bottom = ~> - current = @refs.stream.scroll-top + @refs.stream.offset-height - max = @refs.stream.scroll-height - current > (max - 32) + @on \unmount ~> + @connection.event.off \message @on-message + @connection.event.off \read @on-read + @connection.close! - @scroll-to-bottom = ~> - @refs.stream.scroll-top = @refs.stream.scroll-height + document.remove-event-listener \visibilitychange @on-visibilitychange - @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 + @on \update ~> + @messages.for-each (message) ~> + date = (new Date message.created_at).get-date! + month = (new Date message.created_at).get-month! + 1 + message._date = date + message._datetext = month + '月 ' + date + 'æ—¥' - set-timeout ~> - n.style.opacity = 0 - set-timeout ~> - n.parent-node.remove-child n - , 1000ms - , 4000ms + @on-message = (message) ~> + is-bottom = @is-bottom! - @on-visibilitychange = ~> - if document.hidden then return - @messages.for-each (message) ~> - if message.user_id != @I.id and not message.is_read + @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! + + @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> diff --git a/src/web/app/desktop/tags/messaging/window.tag b/src/web/app/desktop/tags/messaging/window.tag index b6979b62440487c95c8735be187da72207a1603a..17ebfd22807c1cdb00895f744f0cf9372dd21830 100644 --- a/src/web/app/desktop/tags/messaging/window.tag +++ b/src/web/app/desktop/tags/messaging/window.tag @@ -1,29 +1,28 @@ -mk-messaging-window - mk-window@window(is-modal={ false }, width={ '500px' }, height={ '560px' }) - <yield to="header"> - i.fa.fa-comments - | メッセージ - </yield> - <yield to="content"> - mk-messaging@index - </yield> +<mk-messaging-window> + <mk-window ref="window" is-modal="{ false }" width="{ '500px' }" height="{ '560px' }"><yield to="header"><i class="fa fa-comments"></i>メッセージ</yield> +<yield to="content"> + <mk-messaging ref="index"></mk-messaging></yield> + </mk-window> + <style type="stylus"> + :scope + > mk-window + [data-yield='header'] + > i + margin-right 4px -style. - > mk-window - [data-yield='header'] - > i - margin-right 4px + [data-yield='content'] + > mk-messaging + height 100% - [data-yield='content'] - > mk-messaging - height 100% + </style> + <script> + @on \mount ~> + @refs.window.on \closed ~> + @unmount! -script. - @on \mount ~> - @refs.window.on \closed ~> - @unmount! - - @refs.window.refs.index.on \navigate-user (user) ~> - w = document.body.append-child document.create-element \mk-messaging-room-window - riot.mount w, do - user: user + @refs.window.refs.index.on \navigate-user (user) ~> + w = document.body.append-child document.create-element \mk-messaging-room-window + riot.mount w, do + user: user + </script> +</mk-messaging-window> diff --git a/src/web/app/desktop/tags/notifications.tag b/src/web/app/desktop/tags/notifications.tag index d47815a89be15b95a0b0007a488e0c1953af2804..b8f03fb6f2fb1a7847014a9e06df252773cdbbf6 100644 --- a/src/web/app/desktop/tags/notifications.tag +++ b/src/web/app/desktop/tags/notifications.tag @@ -1,226 +1,199 @@ -mk-notifications - div.notifications(if={ notifications.length != 0 }) - virtual(each={ notification, i in notifications }) - div.notification(class={ notification.type }) - mk-time(time={ notification.created_at }) - - div.main(if={ notification.type == 'like' }) - 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-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 } +<mk-notifications> + <div class="notifications" if="{ notifications.length != 0 }"> + <virtual each="{ notification, i in notifications }"> + <div class="notification { notification.type }"> + <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 == '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 + > .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 - i - margin-right 4px + p + margin 0 - .post-preview - color rgba(0, 0, 0, 0.7) + i + margin-right 4px - .post-ref - color rgba(0, 0, 0, 0.7) + .post-preview + 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 + .post-ref + color rgba(0, 0, 0, 0.7) - &:before - content "\f10d" + &:before, &:after + font-family FontAwesome + font-size 1em + font-weight normal + font-style normal + display inline-block + margin-right 3px - &:after - content "\f10e" + &:before + content "\f10d" - &.like - .text p i - color #FFAC33 + &:after + content "\f10e" - &.repost, &.quote - .text p i - color #77B255 + &.like + .text p i + color #FFAC33 - &.follow - .text p i - color #53c7ce + &.repost, &.quote + .text p i + color #77B255 - &.reply, &.mention - .text p i - color #555 + &.follow + .text p i + color #53c7ce - > .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! - .catch (err, text-status) -> - console.error err + &.reply, &.mention + .text p i + color #555 - @stream.on \notification @on-notification + > .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) - @on \unmount ~> - @stream.off \notification @on-notification + span + margin 0 16px - @on-notification = (notification) ~> - @notifications.unshift notification - @update! + 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 + + </style> + <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! + .catch (err, text-status) -> + console.error err + + @stream.on \notification @on-notification + + @on \unmount ~> + @stream.off \notification @on-notification + + @on-notification = (notification) ~> + @notifications.unshift notification + @update! - @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 + 'æ—¥' + @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 + 'æ—¥' + </script> +</mk-notifications> diff --git a/src/web/app/desktop/tags/pages/entrance.tag b/src/web/app/desktop/tags/pages/entrance.tag index 5e18f616a3338d9c55844b6bae1c5309c3f418f9..4e1c5277a37fe64ef9cdd8d10d2b40cae17458c2 100644 --- a/src/web/app/desktop/tags/pages/entrance.tag +++ b/src/web/app/desktop/tags/pages/entrance.tag @@ -1,77 +1,80 @@ -mk-entrance - main - img(src='/_/resources/title.svg', alt='Misskey') - - mk-entrance-signin(if={ mode == 'signin' }) - mk-entrance-signup(if={ mode == 'signup' }) - div.introduction(if={ mode == 'introduction' }) - mk-introduction - button(onclick={ signin }) ã‚ã‹ã£ãŸ - - mk-forkit - - footer - mk-copyright - - // ↓ https://github.com/riot/riot/issues/2134 (å°†æ¥çš„) - style(data-disable-scope). +<mk-entrance> + <main><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> + <div class="introduction" if="{ mode == 'introduction' }"> + <mk-introduction></mk-introduction> + <button onclick="{ signin }">ã‚ã‹ã£ãŸ</button> + </div> + </main> + <mk-forkit></mk-forkit> + <footer> + <mk-copyright></mk-copyright> + </footer> + <!-- ↓ https://github.com/riot/riot/issues/2134 (å°†æ¥çš„)--> + <style data-disable-scope="data-disable-scope"> #wait { right: auto; left: 15px; } -style. - display block - height 100% - - > main - display block - - > img + </style> + <style type="stylus"> + :scope display block - width 160px - height 170px - margin 0 auto - pointer-events none - user-select none + height 100% - > .introduction - 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 + > main display block - margin 16px auto 0 auto - color #666 - - &:hover - text-decoration underline - > footer - > mk-copyright - margin 0 - text-align center - line-height 64px - font-size 10px - color rgba(#000, 0.5) - -script. - @mode = \signin + > img + display block + width 160px + height 170px + margin 0 auto + pointer-events none + user-select none + + > .introduction + 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 + margin 16px auto 0 auto + color #666 + + &: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 - @signup = ~> - @mode = \signup - @update! + @signup = ~> + @mode = \signup + @update! - @signin = ~> - @mode = \signin - @update! + @signin = ~> + @mode = \signin + @update! - @introduction = ~> - @mode = \introduction - @update! + @introduction = ~> + @mode = \introduction + @update! + </script> +</mk-entrance> diff --git a/src/web/app/desktop/tags/pages/entrance/signin.tag b/src/web/app/desktop/tags/pages/entrance/signin.tag index 8ff39bc296b8c6922ba986e890d377f126d81ac6..26bdb6898ae1ef4ac8482552a3cac6da7c5a1da6 100644 --- a/src/web/app/desktop/tags/pages/entrance/signin.tag +++ b/src/web/app/desktop/tags/pages/entrance/signin.tag @@ -1,128 +1,130 @@ -mk-entrance-signin - a.help(href={ CONFIG.urls.about + '/help' }, title='ãŠå›°ã‚Šã§ã™ã‹ï¼Ÿ'): i.fa.fa-question - div.form - h1 - img(if={ user }, src={ user.avatar_url + '?thumbnail&size=32' }) - p { user ? user.name : 'アカウント' } - mk-signin@signin - div.divider: span or - button.signup(onclick={ parent.signup }) æ–°è¦ç™»éŒ² - a.introduction(onclick={ introduction }) Misskeyã«ã¤ã„㦠- -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 +<mk-entrance-signin><a class="help" href="{ CONFIG.urls.about + '/help' }" title="ãŠå›°ã‚Šã§ã™ã‹ï¼Ÿ"><i class="fa fa-question"></i></a> + <div class="form"> + <h1><img if="{ user }" src="{ user.avatar_url + '?thumbnail&size=32' }"/> + <p>{ user ? user.name : 'アカウント' }</p> + </h1> + <mk-signin ref="signin"></mk-signin> + </div> + <div class="divider"><span>or</span></div> + <button class="signup" onclick="{ parent.signup }">æ–°è¦ç™»éŒ²</button><a class="introduction" onclick="{ introduction }">Misskeyã«ã¤ã„ã¦</a> + <style type="stylus"> + :scope display block - margin 0 - padding 0 - height 54px - line-height 54px + width 290px + margin 0 auto 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 + + &:hover + > .help + opacity 1 + + > .help + cursor pointer + display block + position absolute + top 0 + right 0 + z-index 1 margin 0 padding 0 - - > img + 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 + 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 - 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 - margin-top 16px - font-size 12px - color #666 - -script. - @on \mount ~> - @refs.signin.on \user (user) ~> - @update do - user: user - - @introduction = ~> - @parent.introduction! + margin-top 16px + font-size 12px + color #666 + + </style> + <script> + @on \mount ~> + @refs.signin.on \user (user) ~> + @update do + user: user + + @introduction = ~> + @parent.introduction! + </script> +</mk-entrance-signin> diff --git a/src/web/app/desktop/tags/pages/entrance/signup.tag b/src/web/app/desktop/tags/pages/entrance/signup.tag index 1b585f70000ed6f85bc7a922793b1719a1d5e177..2452b7d7939320d9cb12c8b7d71de5f019dd0219 100644 --- a/src/web/app/desktop/tags/pages/entrance/signup.tag +++ b/src/web/app/desktop/tags/pages/entrance/signup.tag @@ -1,44 +1,51 @@ -mk-entrance-signup - mk-signup - button.cancel(type='button', onclick={ parent.signin }, title='ã‚ャンセル'): i.fa.fa-times - -style. - display block - width 368px - margin 0 auto - - &:hover - > .cancel - opacity 1 - - > mk-signup - padding 18px 32px 0 32px - background #fff - box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2) - - > .cancel - 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 - box-shadow none - background transparent - opacity 0 - transition opacity 0.1s ease - - &:hover - color #555 - - &:active - color #222 - - > i - padding 14px +<mk-entrance-signup> + <mk-signup></mk-signup> + <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 + + &:hover + > .cancel + opacity 1 + + > mk-signup + padding 18px 32px 0 32px + background #fff + box-shadow 0px 4px 16px rgba(0, 0, 0, 0.2) + + > .cancel + 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 + box-shadow none + background transparent + opacity 0 + transition opacity 0.1s ease + + &:hover + color #555 + + &:active + color #222 + + > i + padding 14px + + + + + + </style> +</mk-entrance-signup> diff --git a/src/web/app/desktop/tags/pages/home.tag b/src/web/app/desktop/tags/pages/home.tag index 5d419a5802109f67365450738983ca71c1e280e9..3a0e713d301c5d2124e73e025c71b5afe433a489 100644 --- a/src/web/app/desktop/tags/pages/home.tag +++ b/src/web/app/desktop/tags/pages/home.tag @@ -1,51 +1,56 @@ -mk-home-page - mk-ui@ui(page={ page }): mk-home@home(mode={ parent.opts.mode }) - -style. - display block - - background-position center center - background-attachment fixed - background-size cover - -script. - @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 - - @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 +<mk-home-page> + <mk-ui ref="ui" page="{ page }"> + <mk-home ref="home" mode="{ parent.opts.mode }"></mk-home> + </mk-ui> + <style type="stylus"> + :scope + display block + + background-position center center + background-attachment fixed + background-size cover + + </style> + <script> + @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 + + @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' + </script> +</mk-home-page> diff --git a/src/web/app/desktop/tags/pages/not-found.tag b/src/web/app/desktop/tags/pages/not-found.tag index fe23cc6fa423a451127657b07f5e7422bed7f21e..e3db8c0f705a10e868b1aa8f261e1b6fec0dcd91 100644 --- a/src/web/app/desktop/tags/pages/not-found.tag +++ b/src/web/app/desktop/tags/pages/not-found.tag @@ -1,46 +1,54 @@ -mk-not-found - mk-ui - main - h1 Not Found - img(src='/_/resources/rogge.jpg', alt='') - div.mask +<mk-not-found> + <mk-ui> + <main> + <h1>Not Found</h1><img src="/_/resources/rogge.jpg" alt=""/> + <div class="mask"></div> + </main> + </mk-ui> + <style type="stylus"> + :scope + display block -style. - display block + main + display block + width 600px + margin 32px auto - main - display block - width 600px - margin 32px auto + > img + 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) - > img - 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 + 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 - > 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 + + + + - > .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> diff --git a/src/web/app/desktop/tags/pages/post.tag b/src/web/app/desktop/tags/pages/post.tag index 81ab9ce0063e4e73bb1b4d89c9194bfba103517e..f355770d38710e6a1131ada9c557ca63c3b1dbfa 100644 --- a/src/web/app/desktop/tags/pages/post.tag +++ b/src/web/app/desktop/tags/pages/post.tag @@ -1,25 +1,32 @@ -mk-post-page - mk-ui@ui: main: mk-post-detail@detail(post={ parent.post }) - -style. - display block - - main - padding 16px - - > mk-post-detail - margin 0 auto - -script. - @mixin \ui-progress - - @post = @opts.post - - @on \mount ~> - @Progress.start! - - @refs.ui.refs.detail.on \post-fetched ~> - @Progress.set 0.5 - - @refs.ui.refs.detail.on \loaded ~> - @Progress.done! +<mk-post-page> + <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 + + main + padding 16px + + > mk-post-detail + margin 0 auto + + </style> + <script> + @mixin \ui-progress + + @post = @opts.post + + @on \mount ~> + @Progress.start! + + @refs.ui.refs.detail.on \post-fetched ~> + @Progress.set 0.5 + + @refs.ui.refs.detail.on \loaded ~> + @Progress.done! + </script> +</mk-post-page> diff --git a/src/web/app/desktop/tags/pages/search.tag b/src/web/app/desktop/tags/pages/search.tag index a7878ddc0fa7b76d9bae421539e5e7163210de33..a3b3bafd995a46cb68a910966b12d81fc6d12699 100644 --- a/src/web/app/desktop/tags/pages/search.tag +++ b/src/web/app/desktop/tags/pages/search.tag @@ -1,14 +1,19 @@ -mk-search-page - mk-ui@ui: mk-search@search(query={ parent.opts.query }) +<mk-search-page> + <mk-ui ref="ui"> + <mk-search ref="search" query="{ parent.opts.query }"></mk-search> + </mk-ui> + <style type="stylus"> + :scope + display block -style. - display block + </style> + <script> + @mixin \ui-progress -script. - @mixin \ui-progress + @on \mount ~> + @Progress.start! - @on \mount ~> - @Progress.start! - - @refs.ui.refs.search.on \loaded ~> - @Progress.done! + @refs.ui.refs.search.on \loaded ~> + @Progress.done! + </script> +</mk-search-page> diff --git a/src/web/app/desktop/tags/pages/user.tag b/src/web/app/desktop/tags/pages/user.tag index d41093c298691bb13584e445a4e168a6b7d2ff7a..d6587e8132ec9df2f76d693c116fe5ffef2021d8 100644 --- a/src/web/app/desktop/tags/pages/user.tag +++ b/src/web/app/desktop/tags/pages/user.tag @@ -1,20 +1,25 @@ -mk-user-page - mk-ui@ui: mk-user@user(user={ parent.user }, page={ parent.opts.page }) +<mk-user-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. - display block + </style> + <script> + @mixin \ui-progress -script. - @mixin \ui-progress + @user = @opts.user - @user = @opts.user + @on \mount ~> + @Progress.start! - @on \mount ~> - @Progress.start! + @refs.ui.refs.user.on \user-fetched (user) ~> + @Progress.set 0.5 + document.title = user.name + ' | Misskey' - @refs.ui.refs.user.on \user-fetched (user) ~> - @Progress.set 0.5 - document.title = user.name + ' | Misskey' - - @refs.ui.refs.user.on \loaded ~> - @Progress.done! + @refs.ui.refs.user.on \loaded ~> + @Progress.done! + </script> +</mk-user-page> diff --git a/src/web/app/desktop/tags/post-detail-sub.tag b/src/web/app/desktop/tags/post-detail-sub.tag index b7aa7457372b81fab1a9f2e6c755369fd27b05f3..8b6411c12a11dc6eab621ff916d7c98a8e9e73ca 100644 --- a/src/web/app/desktop/tags/post-detail-sub.tag +++ b/src/web/app/desktop/tags/post-detail-sub.tag @@ -1,141 +1,140 @@ -mk-post-detail-sub(title={ title }) - a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }) - img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ post.user_id }) - div.main - header - div.left - a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id }) - | { post.user.name } - span.username - | @{ post.user.username } - div.right - a.time(href={ url }) - mk-time(time={ post.created_at }) - div.body - div.text@text - div.media(if={ post.media }) - 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 +<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> + <div class="main"> + <header> + <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> + <div class="right"><a class="time" href="{ url }"> + <mk-time time="{ post.created_at }"></mk-time></a></div> + </header> + <div class="body"> + <div class="text" ref="text"></div> + <div class="media" if="{ post.media }"> + <virtual each="{ file in post.media }"><img src="{ file.url + '?thumbnail&size=512' }" alt="{ file.name }" title="{ file.name }"/></virtual> + </div> + </div> + </div> + <style type="stylus"> + :scope display block - width 44px - height 44px margin 0 - border-radius 4px - vertical-align bottom - - > .main - float left - width calc(100% - 60px) - - > header - margin-bottom 4px - white-space nowrap + padding 20px 32px + background #fdfdfd &: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 - - > .right - float right + &:hover + > .main > footer > button + color #888 - > .time - font-size 0.9em - color #c0c0c0 - - > .body - - > .text - cursor default + > .avatar-anchor display block - margin 0 - padding 0 - word-wrap break-word - font-size 1em - color #717171 - - > mk-url-preview - margin-top 8px + float left + margin 0 16px 0 0 - > .media - > img + > .avatar display block - max-width 100% - -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! + width 44px + height 44px + margin 0 + border-radius 4px + vertical-align bottom + + > .main + float left + width calc(100% - 60px) + + > header + margin-bottom 4px + 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 + + > .right + float right + + > .time + font-size 0.9em + color #c0c0c0 + + > .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> diff --git a/src/web/app/desktop/tags/post-detail.tag b/src/web/app/desktop/tags/post-detail.tag index e071b7c7043b40d7685dc523397f93ef6969b8b8..c395a44328ff84ace227e5c49397b673194bec4a 100644 --- a/src/web/app/desktop/tags/post-detail.tag +++ b/src/web/app/desktop/tags/post-detail.tag @@ -1,415 +1,409 @@ -mk-post-detail(title={ title }) - - div.fetching(if={ fetching }) - mk-ellipsis-icon - - div.main(if={ !fetching }) - - button.read-more(if={ p.reply_to && p.reply_to.reply_to_id && context == null }, title='会話をもã£ã¨èªã¿è¾¼ã‚€', onclick={ load-context }, disabled={ loading-context }) - i.fa.fa-ellipsis-v(if={ !loading-context }) - i.fa.fa-spinner.fa-pulse(if={ loading-context }) - - div.context - virtual(each={ post in context }) - mk-post-detail-sub(post={ post }) - - div.reply-to(if={ p.reply_to }) - mk-post-detail-sub(post={ p.reply_to }) - - div.repost(if={ is-repost }) - p - 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') - i.fa.fa-retweet - a.name(href={ CONFIG.url + '/' + post.user.username }) { post.user.name } - | ãŒRepost - - article - a.avatar-anchor(href={ CONFIG.url + '/' + p.user.username }) - img.avatar(src={ p.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ p.user.id }) - header - a.name(href={ CONFIG.url + '/' + p.user.username }, data-user-preview={ p.user.id }) - | { p.user.name } - span.username - | @{ p.user.username } - a.time(href={ url }) - mk-time(time={ p.created_at }) - div.body - div.text@text - div.media(if={ p.media }) - virtual(each={ file in p.media }) - img(src={ file.url + '?thumbnail&size=512' }, alt={ file.name }, title={ file.name }) - footer - button(onclick={ reply }, title='返信') - i.fa.fa-reply - p.count(if={ p.replies_count > 0 }) { p.replies_count } - button(onclick={ repost }, title='Repost') - i.fa.fa-retweet - p.count(if={ p.repost_count > 0 }) { p.repost_count } - button(class={ liked: p.is_liked }, onclick={ like }, title='善哉') - i.fa.fa-thumbs-o-up - p.count(if={ p.likes_count > 0 }) { p.likes_count } - button(onclick={ NotImplementedException }): i.fa.fa-ellipsis-h - div.reposts-and-likes - div.reposts(if={ reposts && reposts.length > 0 }) - header - a { p.repost_count } - p Repost - ol.users - li.user(each={ reposts }) - a.avatar-anchor(href={ CONFIG.url + '/' + user.username }, title={ user.name }, data-user-preview={ user.id }) - img.avatar(src={ user.avatar_url + '?thumbnail&size=32' }, alt='') - div.likes(if={ likes && likes.length > 0 }) - header - a { p.likes_count } - p ã„ã„ã - ol.users - 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 +<mk-post-detail title="{ title }"> + <div class="fetching" if="{ fetching }"> + <mk-ellipsis-icon></mk-ellipsis-icon> + </div> + <div class="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"> + <virtual each="{ post in context }"> + <mk-post-detail-sub post="{ post }"></mk-post-detail-sub> + </virtual> + </div> + <div class="reply-to" if="{ p.reply_to }"> + <mk-post-detail-sub post="{ p.reply_to }"></mk-post-detail-sub> + </div> + <div class="repost" if="{ isRepost }"> + <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> + </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> + <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 }"> + <mk-time time="{ p.created_at }"></mk-time></a></header> + <div class="body"> + <div class="text" ref="text"></div> + <div class="media" if="{ p.media }"> + <virtual each="{ file in p.media }"><img src="{ file.url + '?thumbnail&size=512' }" alt="{ file.name }" title="{ file.name }"/></virtual> + </div> + </div> + <footer> + <button onclick="{ reply }" title="返信"><i class="fa fa-reply"></i> + <p class="count" if="{ p.replies_count > 0 }">{ p.replies_count }</p> + </button> + <button onclick="{ repost }" title="Repost"><i class="fa fa-retweet"></i> + <p class="count" if="{ p.repost_count > 0 }">{ p.repost_count }</p> + </button> + <button class="{ liked: p.is_liked }" onclick="{ like }" title="善哉"><i class="fa fa-thumbs-o-up"></i> + <p class="count" if="{ p.likes_count > 0 }">{ p.likes_count }</p> + </button> + <button onclick="{ NotImplementedException }"><i class="fa fa-ellipsis-h"></i></button> + </footer> + <div class="reposts-and-likes"> + <div class="reposts" if="{ reposts && reposts.length > 0 }"> + <header><a>{ p.repost_count }</a> + <p>Repost</p> + </header> + <ol class="users"> + <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> + </ol> + </div> + <div class="likes" if="{ likes && likes.length > 0 }"> + <header><a>{ p.likes_count }</a> + <p>ã„ã„ã</p> + </header> + <ol class="users"> + <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> + </ol> + </div> + </div> + </article> + <div class="replies"> + <virtual each="{ post in replies }"> + <mk-post-detail-sub post="{ post }"></mk-post-detail-sub> + </virtual> + </div> + </div> + <style type="stylus"> + :scope display block margin 0 - padding 10px 0 - width 100% - font-size 1em - text-align center - color #999 - cursor pointer - background #fafafa - outline none - border none - border-bottom solid 1px #eef0f2 - border-radius 6px 6px 0 0 - - &:hover - background #f6f6f6 - - &:active - background #f0f0f0 - - &:disabled - 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 - width 60px - height 60px - margin 0 - border-radius 8px - vertical-align bottom + padding 0 + width 640px + overflow hidden + background #fff + border solid 1px rgba(0, 0, 0, 0.1) + border-radius 8px + + > .fetching + padding 64px 0 - > header - position absolute - top 28px - left 108px - width calc(100% - 108px) + > .main - > .name - display inline-block + > .read-more + display block margin 0 - line-height 24px - color #777 - font-size 18px - font-weight 700 - text-align left - text-decoration none + padding 10px 0 + width 100% + font-size 1em + text-align center + color #999 + cursor pointer + background #fafafa + outline none + border none + border-bottom solid 1px #eef0f2 + border-radius 6px 6px 0 0 &:hover - text-decoration underline + background #f6f6f6 - > .username - display block - text-align left - margin 0 - color #ccc + &:active + background #f0f0f0 - > .time - position absolute - top 0 - right 32px - font-size 1em - color #c0c0c0 + &:disabled + color #ccc - > .body - padding 8px 0 + > .context + > * + border-bottom 1px solid #eef0f2 - > .text - cursor default - display block - margin 0 - padding 0 - word-wrap break-word - font-size 1.5em - color #717171 + > .repost + color #9dbb00 + background linear-gradient(to bottom, #edfde2 0%, #fff 100%) - > mk-url-preview - margin-top 8px + > p + margin 0 + padding 16px 32px - > .media - > img - display block - max-width 100% + .avatar-anchor + display inline-block - > footer - font-size 1.2em + .avatar + vertical-align bottom + min-width 28px + min-height 28px + max-width 28px + max-height 28px + margin 0 8px 0 0 + border-radius 6px - > button - margin 0 28px 0 0 - padding 8px - background transparent - border none - font-size 1em - color #ddd - cursor pointer + i + margin-right 4px - &:hover - color #666 + .name + font-weight bold - > .count - display inline - margin 0 0 0 8px - color #999 + & + article + padding-top 8px - &.liked - color $theme-color + > .reply-to + border-bottom 1px solid #eef0f2 - > .reposts-and-likes - display flex - justify-content center - padding 0 - margin 16px 0 + > article + padding 28px 32px 18px 32px - &:empty - display none + &:after + content "" + display block + clear both - > .reposts - > .likes - display flex - flex 1 1 - padding 0 - border-top solid 1px #F2EFEE + &:hover + > .main > footer > button + color #888 - > header - flex 1 1 80px - max-width 80px - padding 8px 5px 0px 10px + > .avatar-anchor + display block + width 60px + height 60px - > a + > .avatar display block - font-size 1.5em - line-height 1.4em + width 60px + height 60px + margin 0 + border-radius 8px + vertical-align bottom - > p + > 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 - font-size 0.7em - line-height 1em - font-weight normal - color #a0a2a5 + color #ccc - > .users - display block - flex 1 1 - margin 0 - padding 10px 10px 10px 5px - list-style none + > .time + position absolute + top 0 + right 32px + font-size 1em + color #c0c0c0 + + > .body + padding 8px 0 - > .user + > .text + cursor default display block - float left - margin 4px + 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 + + &:hover + color #666 + + > .count + display inline + margin 0 0 0 8px + color #999 + + &.liked + color $theme-color + + > .reposts-and-likes + display flex + justify-content center + padding 0 + margin 16px 0 + + &:empty + display none + + > .reposts + > .likes + display flex + flex 1 1 padding 0 + border-top solid 1px #F2EFEE + + > header + flex 1 1 80px + max-width 80px + padding 8px 5px 0px 10px + + > a + display block + font-size 1.5em + line-height 1.4em + + > p + display block + 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 + + > .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 - > .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 - -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 - - @update! - - if @p.text? - tokens = @analyze @p.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 - - # 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! + if @p.text? + tokens = @analyze @p.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 + + # 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! - # Get replies - @api \posts/replies do - post_id: @p.id - limit: 8 - .then (replies) ~> - @replies = replies @update! - @update! - - @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 + @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! - - @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! + </script> +</mk-post-detail> diff --git a/src/web/app/desktop/tags/post-form-window.tag b/src/web/app/desktop/tags/post-form-window.tag index 87277779443e189a61deb4903dafbe3a441d65e8..753dea1adbf5ebb03ef106df6e970025091a2fee 100644 --- a/src/web/app/desktop/tags/post-form-window.tag +++ b/src/web/app/desktop/tags/post-form-window.tag @@ -1,60 +1,55 @@ -mk-post-form-window - - mk-window@window(is-modal={ true }, colored={ true }) - - <yield to="header"> - span(if={ !parent.opts.reply }) æ–°è¦æŠ•ç¨¿ - 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"> - div.ref(if={ parent.opts.reply }) - mk-post-preview(post={ parent.opts.reply }) - div.body - mk-post-form@form(reply={ parent.opts.reply }) - </yield> - -style. - > mk-window - - [data-yield='header'] - > .files - > .uploading-files - margin-left 8px - opacity 0.8 - - &:before - content '(' - - &:after - content ')' - - [data-yield='content'] - > .ref - > mk-post-preview - margin 16px 22px - -script. - @uploading-files = [] - @files = [] - - @on \mount ~> - @refs.window.refs.form.focus! - - @refs.window.on \closed ~> - @unmount! - - @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! +<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 + + [data-yield='header'] + > .files + > .uploading-files + margin-left 8px + opacity 0.8 + + &:before + content '(' + + &:after + content ')' + + [data-yield='content'] + > .ref + > mk-post-preview + margin 16px 22px + + </style> + <script> + @uploading-files = [] + @files = [] + + @on \mount ~> + @refs.window.refs.form.focus! + + @refs.window.on \closed ~> + @unmount! + + @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! + </script> +</mk-post-form-window> diff --git a/src/web/app/desktop/tags/post-form.tag b/src/web/app/desktop/tags/post-form.tag index 22485878858832ad650f8b475d3faefbb8f8c388..3950d6cb07fe211abb560c7f512eec029b5ab809 100644 --- a/src/web/app/desktop/tags/post-form.tag +++ b/src/web/app/desktop/tags/post-form.tag @@ -1,430 +1,434 @@ -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 ? 'ã“ã®æŠ•ç¨¿ã¸ã®è¿”ä¿¡...' : 'ã„ã¾ã©ã†ã—ã¦ã‚‹ï¼Ÿ' }) - div.attaches(if={ files.length != 0 }) - ul.files@attaches - li.file(each={ files }) - div.img(style='background-image: url({ url + "?thumbnail&size=64" })', title={ name }) - img.remove(onclick={ _remove }, src='/_/resources/desktop/remove.png', title='添付å–り消ã—', alt='') - li.add(if={ files.length < 4 }, title='PCã‹ã‚‰ãƒ•ã‚¡ã‚¤ãƒ«ã‚’添付', onclick={ select-file }): i.fa.fa-plus - p.remain - | 残り{ 4 - files.length } - mk-uploader@uploader - button@upload(title='PCã‹ã‚‰ãƒ•ã‚¡ã‚¤ãƒ«ã‚’添付', onclick={ select-file }): i.fa.fa-upload - button@drive(title='ドライブã‹ã‚‰ãƒ•ã‚¡ã‚¤ãƒ«ã‚’添付', onclick={ select-file-from-drive }): i.fa.fa-cloud - p.text-count(class={ over: refs.text.value.length > 300 }) ã®ã“ã‚Š{ 300 - refs.text.value.length }æ–‡å— - button@submit(class={ wait: wait }, disabled={ wait || (refs.text.value.length == 0 && files.length == 0) }, onclick={ post }) - | { wait ? '投稿ä¸' : opts.reply ? '返信' : '投稿' } - mk-ellipsis(if={ wait }) - input@file(type='file', accept='image/*', multiple, tabindex='-1', onchange={ change-file }) - div.dropzone(if={ draghover }) - -style. - display block - 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 +<mk-post-form ondragover="{ ondragover }" ondragenter="{ ondragenter }" ondragleave="{ ondragleave }" ondrop="{ ondrop }"> + <textarea class="{ withfiles: files.length != 0 }" ref="text" disabled="{ wait }" oninput="{ update }" onkeydown="{ onkeydown }" onpaste="{ onpaste }" placeholder="{ opts.reply ? 'ã“ã®æŠ•ç¨¿ã¸ã®è¿”ä¿¡...' : 'ã„ã¾ã©ã†ã—ã¦ã‚‹ï¼Ÿ' }"></textarea> + <div class="attaches" if="{ files.length != 0 }"> + <ul class="files" ref="attaches"> + <li class="file" each="{ files }"> + <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=""/> + </li> + <li class="add" if="{ files.length < 4 }" title="PCã‹ã‚‰ãƒ•ã‚¡ã‚¤ãƒ«ã‚’添付" onclick="{ selectFile }"><i class="fa fa-plus"></i></li> + </ul> + <p class="remain">残り{ 4 - files.length }</p> + </div> + <mk-uploader ref="uploader"></mk-uploader> + <button ref="upload" title="PCã‹ã‚‰ãƒ•ã‚¡ã‚¤ãƒ«ã‚’添付" onclick="{ selectFile }"><i class="fa fa-upload"></i></button> + <button ref="drive" title="ドライブã‹ã‚‰ãƒ•ã‚¡ã‚¤ãƒ«ã‚’添付" onclick="{ selectFileFromDrive }"><i class="fa fa-cloud"></i></button> + <p class="text-count { over: refs.text.value.length > 300 }">ã®ã“ã‚Š{ 300 - refs.text.value.length }æ–‡å—</p> + <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> + </button> + <input ref="file" type="file" accept="image/*" multiple="multiple" tabindex="-1" onchange="{ changeFile }"/> + <div class="dropzone" if="{ draghover }"></div> + <style type="stylus"> + :scope display block - position absolute - top 8px - right 8px - margin 0 - padding 0 - color rgba($theme-color, 0.4) - - > .files - display block - margin 0 - padding 4px - list-style none + padding 16px + background lighten($theme-color, 95%) &:after content "" display block clear both - > .file - display block - float left - margin 4px + > .attaches + margin 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 + position absolute + top 8px + right 8px + margin 0 + padding 0 + color rgba($theme-color, 0.4) - > .img - width 64px - height 64px - background-size cover - background-position center center + > .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 + 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 - > .remove - display none - position absolute - top -6px - right -6px - width 16px - height 16px - cursor pointer + &:hover + border-color rgba($theme-color, 0.2) + transition border-color .1s ease - > .add + &: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 - float left - margin 4px + 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 - border dashed 2px rgba($theme-color, 0.2) + 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) - > 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 - 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 + &: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 + position absolute + top -5px + right -5px + bottom -5px + left -5px + border 2px solid rgba($theme-color, 0.3) + border-radius 8px + + > .dropzone 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) - - &: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 "" + left 0 + top 0 + width 100% + height 100% + border dashed 2px rgba($theme-color, 0.5) 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 - position absolute - left 0 - top 0 - width 100% - height 100% - border dashed 2px rgba($theme-color, 0.5) - pointer-events none - -script. - @mixin \api - @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 = '' + + </style> + <script> + @mixin \api + @mixin \notify + @mixin \autocomplete + @mixin \sortable + + @wait = false + @uploadings = [] @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 + @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 = [] + @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 - # データå–å¾— - data = e.data-transfer.get-data 'text' - if !data? + @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 - 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) ~> - @refs.uploader.upload file - - @add-file = (file) ~> - file._remove = ~> - @files = @files.filter (x) -> x.id != file.id + @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 + @update! + + @files.push file @trigger \change-files @files @update! - @files.push file - @trigger \change-files @files - @update! - - new @Sortable @refs.attaches, do - draggable: \.file - animation: 150ms - - @post = (e) ~> - @wait = true - - files = if @files? and @files.length > 0 - then @files.map (f) -> f.id - else undefined - - @api \posts/create do - text: @refs.text.value - media_ids: files - reply_to_id: if @in-reply-to-post? then @in-reply-to-post.id else undefined - .then (data) ~> - @trigger \post - @notify if @in-reply-to-post? then '返信ã—ã¾ã—ãŸï¼' else '投稿ã—ã¾ã—ãŸï¼' - .catch (err) ~> - console.error err - @notify '投稿ã§ãã¾ã›ã‚“ã§ã—ãŸ' - .then ~> - @wait = false - @update! + new @Sortable @refs.attaches, do + draggable: \.file + animation: 150ms + + @post = (e) ~> + @wait = true + + files = if @files? and @files.length > 0 + then @files.map (f) -> f.id + else undefined + + @api \posts/create do + text: @refs.text.value + media_ids: files + reply_to_id: if @in-reply-to-post? then @in-reply-to-post.id else undefined + .then (data) ~> + @trigger \post + @notify if @in-reply-to-post? then '返信ã—ã¾ã—ãŸï¼' else '投稿ã—ã¾ã—ãŸï¼' + .catch (err) ~> + console.error err + @notify '投稿ã§ãã¾ã›ã‚“ã§ã—ãŸ' + .then ~> + @wait = false + @update! + </script> +</mk-post-form> diff --git a/src/web/app/desktop/tags/post-preview.tag b/src/web/app/desktop/tags/post-preview.tag index f17b152801fdca34f911ee5fca1cf729fcdcd436..4035261782b745dc356dc7f004e62397b5299d4b 100644 --- a/src/web/app/desktop/tags/post-preview.tag +++ b/src/web/app/desktop/tags/post-preview.tag @@ -1,94 +1,93 @@ -mk-post-preview(title={ title }) - article - a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }) - img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ post.user_id }) - div.main - header - a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id }) - | { post.user.name } - span.username - | @{ post.user.username } - a.time(href={ CONFIG.url + '/' + post.user.username + '/' + post.id }) - mk-time(time={ post.created_at }) - 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 "" +<mk-post-preview title="{ title }"> + <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> + <div class="main"> + <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 }"> + <mk-time time="{ post.created_at }"></mk-time></a></header> + <div class="body"> + <mk-sub-post-content class="text" post="{ post }"></mk-sub-post-content> + </div> + </div> + </article> + <style type="stylus"> + :scope 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 52px - height 52px - margin 0 - border-radius 8px - vertical-align bottom - - > .main - float left - width calc(100% - 68px) - - > header - margin-bottom 4px - white-space nowrap - - > .name - display inline - margin 0 - padding 0 - color #607073 - 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 #d1d8da - - > .time - position absolute - top 0 - right 0 - color #b2b8bb - - > .body - - > .text - cursor default - margin 0 - padding 0 - font-size 1.1em - color #717171 - -script. - @mixin \date-stringify - @mixin \user-preview - - @post = @opts.post - - @title = @date-stringify @post.created_at + margin 0 + padding 0 + font-size 0.9em + background #fff + + > article + + &: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 52px + height 52px + margin 0 + border-radius 8px + vertical-align bottom + + > .main + float left + width calc(100% - 68px) + + > header + margin-bottom 4px + white-space nowrap + + > .name + display inline + margin 0 + padding 0 + color #607073 + 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 #d1d8da + + > .time + position absolute + top 0 + right 0 + color #b2b8bb + + > .body + + > .text + cursor default + margin 0 + padding 0 + font-size 1.1em + color #717171 + + </style> + <script> + @mixin \date-stringify + @mixin \user-preview + + @post = @opts.post + + @title = @date-stringify @post.created_at + </script> +</mk-post-preview> diff --git a/src/web/app/desktop/tags/post-status-graph.tag b/src/web/app/desktop/tags/post-status-graph.tag index ffb081e4f388503aa46a6c2a9837c125e41bd633..c6cdb53b47506a924ca7774f97cae458d7ea13a1 100644 --- a/src/web/app/desktop/tags/post-status-graph.tag +++ b/src/web/app/desktop/tags/post-status-graph.tag @@ -1,72 +1,75 @@ -mk-post-status-graph - canvas@canv(width={ opts.width }, height={ opts.height }) +<mk-post-status-graph> + <canvas ref="canv" width="{ opts.width }" height="{ opts.height }"></canvas> + <style type="stylus"> + :scope + display block -style. - display block + > canvas + margin 0 auto - > canvas - margin 0 auto + </style> + <script> + @mixin \api + @mixin \is-promise -script. - @mixin \api - @mixin \is-promise + @post = null + @post-promise = if @is-promise @opts.post then @opts.post else Promise.resolve @opts.post - @post = null - @post-promise = if @is-promise @opts.post then @opts.post else Promise.resolve @opts.post + @on \mount ~> + post <~ @post-promise.then + @post = post + @update! - @on \mount ~> - 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 + @api \aggregation/posts/like do post_id: @post.id limit: 30days - .then (repost) ~> - repost = repost.reverse! + .then (likes) ~> + likes = likes.reverse! - @api \aggregation/posts/reply do + @api \aggregation/posts/repost do post_id: @post.id limit: 30days - .then (replies) ~> - replies = replies.reverse! + .then (repost) ~> + repost = repost.reverse! + + @api \aggregation/posts/reply do + post_id: @post.id + limit: 30days + .then (replies) ~> + replies = replies.reverse! - new Chart @refs.canv, do - type: \bar - data: - labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + 'æ—¥' else '' - datasets: [ - { - label: \ã„ã„ã - type: \line - data: likes.map (x) ~> x.count - line-tension: 0 - border-width: 2 - fill: true - background-color: 'rgba(247, 121, 108, 0.2)' - point-background-color: \#fff - point-radius: 4 - point-border-width: 2 - border-color: \#F7796C - }, - { - label: \返信 - type: \bar - data: replies.map (x) ~> x.count - background-color: \#555 - }, - { - label: \Repost - type: \bar - data: repost.map (x) ~> x.count - background-color: \#a2d61e - } - ] - options: - responsive: false + new Chart @refs.canv, do + type: \bar + data: + labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + 'æ—¥' else '' + datasets: [ + { + label: \ã„ã„ã + type: \line + data: likes.map (x) ~> x.count + line-tension: 0 + border-width: 2 + fill: true + background-color: 'rgba(247, 121, 108, 0.2)' + point-background-color: \#fff + point-radius: 4 + point-border-width: 2 + border-color: \#F7796C + }, + { + label: \返信 + type: \bar + data: replies.map (x) ~> x.count + background-color: \#555 + }, + { + label: \Repost + type: \bar + data: repost.map (x) ~> x.count + background-color: \#a2d61e + } + ] + options: + responsive: false + </script> +</mk-post-status-graph> diff --git a/src/web/app/desktop/tags/progress-dialog.tag b/src/web/app/desktop/tags/progress-dialog.tag index 7c042686e638b5886deb0e83641030268e0e24b4..48b04d3442bf7dff5e13b36b459930800479c9be 100644 --- a/src/web/app/desktop/tags/progress-dialog.tag +++ b/src/web/app/desktop/tags/progress-dialog.tag @@ -1,92 +1,94 @@ -mk-progress-dialog - mk-window@window(is-modal={ false }, can-close={ false }, width={ '500px' }) - <yield to="header"> - | { parent.title } - mk-ellipsis - </yield> - <yield to="content"> - div.body - p.init(if={ isNaN(parent.value) }) - | å¾…æ©Ÿä¸ - mk-ellipsis - p.percentage(if={ !isNaN(parent.value) }) { Math.floor((parent.value / parent.max) * 100) } - progress(if={ !isNaN(parent.value) && parent.value < parent.max }, value={ isNaN(parent.value) ? 0 : parent.value }, max={ parent.max }) - div.progress.waiting(if={ parent.value >= parent.max }) - </yield> +<mk-progress-dialog> + <mk-window ref="window" is-modal="{ false }" can-close="{ false }" width="{ '500px' }"> + <yield to="header">{ parent.title } + <mk-ellipsis></mk-ellipsis></yield> +<yield to="content"> + <div class="body"> + <p class="init" if="{ isNaN(parent.value) }">å¾…æ©Ÿä¸ + <mk-ellipsis></mk-ellipsis> + </p> + <p class="percentage" if="{ !isNaN(parent.value) }">{ Math.floor((parent.value / parent.max) * 100) }</p> + <progress if="{ !isNaN(parent.value) && parent.value < parent.max }" value="{ isNaN(parent.value) ? 0 : parent.value }" max="{ parent.max }"></progress> + <div class="progress waiting" if="{ parent.value >= parent.max }"></div> + </div></yield> + </mk-window> + <style type="stylus"> + :scope + display block -style. - display block + > mk-window + [data-yield='content'] - > mk-window - [data-yield='content'] + > .body + padding 18px 24px 24px 24px - > .body - padding 18px 24px 24px 24px + > .init + display block + margin 0 + text-align center + color rgba(#000, 0.7) - > .init - display block - margin 0 - text-align center - color rgba(#000, 0.7) + > .percentage + display block + margin 0 0 4px 0 + text-align center + line-height 16px + color rgba($theme-color, 0.7) - > .percentage - display block - margin 0 0 4px 0 - text-align center - line-height 16px - color rgba($theme-color, 0.7) + &:after + content '%' - &:after - content '%' + > progress + > .progress + display block + margin 0 + width 100% + height 10px + background transparent + border none + border-radius 4px + overflow hidden - > progress - > .progress - display block - margin 0 - width 100% - height 10px - background transparent - border none - border-radius 4px - overflow hidden + &::-webkit-progress-value + background $theme-color - &::-webkit-progress-value - background $theme-color + &::-webkit-progress-bar + background rgba($theme-color, 0.1) - &::-webkit-progress-bar - background rgba($theme-color, 0.1) + > .progress + 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 - 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 + @keyframes progress-dialog-tag-progress-waiting + from {background-position: 0 0;} + to {background-position: -64px 32px;} - @keyframes progress-dialog-tag-progress-waiting - from {background-position: 0 0;} - to {background-position: -64px 32px;} + </style> + <script> + @title = @opts.title + @value = parse-int @opts.value, 10 + @max = parse-int @opts.max, 10 -script. - @title = @opts.title - @value = parse-int @opts.value, 10 - @max = parse-int @opts.max, 10 + @on \mount ~> + @refs.window.on \closed ~> + @unmount! - @on \mount ~> - @refs.window.on \closed ~> - @unmount! + @update-progress = (value, max) ~> + @value = parse-int value, 10 + @max = parse-int max, 10 + @update! - @update-progress = (value, max) ~> - @value = parse-int value, 10 - @max = parse-int max, 10 - @update! - - @close = ~> - @refs.window.close! + @close = ~> + @refs.window.close! + </script> +</mk-progress-dialog> diff --git a/src/web/app/desktop/tags/repost-form-window.tag b/src/web/app/desktop/tags/repost-form-window.tag index 40012f951f73ff4c07a881e42ce755943415b77a..a1008b475b40b5bf6c5c9bdfa1d6f3d0be23d9ea 100644 --- a/src/web/app/desktop/tags/repost-form-window.tag +++ b/src/web/app/desktop/tags/repost-form-window.tag @@ -1,38 +1,36 @@ -mk-repost-form-window - mk-window@window(is-modal={ true }, colored={ true }) - <yield to="header"> - i.fa.fa-retweet - | ã“ã®æŠ•ç¨¿ã‚’Repostã—ã¾ã™ã‹ï¼Ÿ - </yield> - <yield to="content"> - mk-repost-form@form(post={ parent.opts.post }) - </yield> - -style. - > mk-window - [data-yield='header'] - > i - margin-right 4px - -script. - - @on-document-keydown = (e) ~> - tag = e.target.tag-name.to-lower-case! - if tag != \input and tag != \textarea - if e.which == 27 # Esc +<mk-repost-form-window> + <mk-window ref="window" is-modal="{ true }" colored="{ true }"><yield to="header"><i class="fa fa-retweet"></i>ã“ã®æŠ•ç¨¿ã‚’Repostã—ã¾ã™ã‹ï¼Ÿ</yield> +<yield to="content"> + <mk-repost-form ref="form" post="{ parent.opts.post }"></mk-repost-form></yield> + </mk-window> + <style type="stylus"> + :scope + > mk-window + [data-yield='header'] + > i + margin-right 4px + + </style> + <script> + @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! + + @on \mount ~> + @refs.window.refs.form.on \cancel ~> @refs.window.close! - @on \mount ~> - @refs.window.refs.form.on \cancel ~> - @refs.window.close! - - @refs.window.refs.form.on \posted ~> - @refs.window.close! + @refs.window.refs.form.on \posted ~> + @refs.window.close! - document.add-event-listener \keydown @on-document-keydown + document.add-event-listener \keydown @on-document-keydown - @refs.window.on \closed ~> - @unmount! + @refs.window.on \closed ~> + @unmount! - @on \unmount ~> - document.remove-event-listener \keydown @on-document-keydown + @on \unmount ~> + document.remove-event-listener \keydown @on-document-keydown + </script> +</mk-repost-form-window> diff --git a/src/web/app/desktop/tags/repost-form.tag b/src/web/app/desktop/tags/repost-form.tag index 37fbad251d82b9f35264541327b9184c538aa770..0352cffc1b13717b0f169e41bd12362714b4220f 100644 --- a/src/web/app/desktop/tags/repost-form.tag +++ b/src/web/app/desktop/tags/repost-form.tag @@ -1,140 +1,144 @@ -mk-repost-form - mk-post-preview(post={ opts.post }) - div.form(if={ quote }) - textarea@text(disabled={ wait }, placeholder='ã“ã®æŠ•ç¨¿ã‚’引用...') - footer - a.quote(if={ !quote }, onclick={ onquote }) 引用ã™ã‚‹... - button.cancel(onclick={ cancel }) ã‚ャンセル - button.ok(onclick={ ok }) Repost - -style. - - > mk-post-preview - margin 16px 22px - - > .form - [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 - - &: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) - - > div - padding 16px - - > footer - 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 +<mk-repost-form> + <mk-post-preview post="{ opts.post }"></mk-post-preview> + <div class="form" if="{ quote }"> + <textarea ref="text" disabled="{ wait }" placeholder="ã“ã®æŠ•ç¨¿ã‚’引用..."></textarea> + </div> + <footer><a class="quote" if="{ !quote }" onclick="{ onquote }">引用ã™ã‚‹...</a> + <button class="cancel" onclick="{ cancel }">ã‚ャンセル</button> + <button class="ok" onclick="{ ok }">Repost</button> + </footer> + <style type="stylus"> + :scope + + > mk-post-preview + margin 16px 22px + + > .form + [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 + + &: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) + + > div + padding 16px + + > footer + height 72px + background lighten($theme-color, 95%) + + > .quote position absolute - top -5px - right -5px - bottom -5px - left -5px - border 2px solid rgba($theme-color, 0.3) - border-radius 8px - - > .cancel - right 148px - color #888 - background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) - border solid 1px #e2e2e2 - - &:hover - background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) - border-color #dcdcdc - - &:active - background #ececec - border-color #dcdcdc - - > .ok - right 16px - 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%) - - &:hover - background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%) - border-color $theme-color - - &:active - background $theme-color - border-color $theme-color - -script. - @mixin \api - @mixin \notify - - @wait = false - @quote = false - - @cancel = ~> - @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 + 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 + top -5px + right -5px + bottom -5px + left -5px + border 2px solid rgba($theme-color, 0.3) + border-radius 8px + + > .cancel + right 148px + color #888 + background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) + border solid 1px #e2e2e2 + + &:hover + background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) + border-color #dcdcdc + + &:active + background #ececec + border-color #dcdcdc + + > .ok + right 16px + 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%) + + &:hover + background linear-gradient(to bottom, lighten($theme-color, 8%) 0%, darken($theme-color, 8%) 100%) + border-color $theme-color + + &:active + background $theme-color + border-color $theme-color + + </style> + <script> + @mixin \api + @mixin \notify + + @wait = false + @quote = false + + @cancel = ~> + @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> diff --git a/src/web/app/desktop/tags/search-posts.tag b/src/web/app/desktop/tags/search-posts.tag index 9862ff6e4eb7ea0044322a28a40c0fca972d0622..2d999e84ca22af3d850448d6a6c1b2ae38aaffdf 100644 --- a/src/web/app/desktop/tags/search-posts.tag +++ b/src/web/app/desktop/tags/search-posts.tag @@ -1,88 +1,86 @@ -mk-search-posts - div.loading(if={ is-loading }) - mk-ellipsis-icon - p.empty(if={ is-empty }) - i.fa.fa-search - | 「{ query }ã€ã«é–¢ã™ã‚‹æŠ•ç¨¿ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚ - 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 +<mk-search-posts> + <div class="loading" if="{ isLoading }"> + <mk-ellipsis-icon></mk-ellipsis-icon> + </div> + <p class="empty" if="{ isEmpty }"><i class="fa fa-search"></i>「{ query }ã€ã«é–¢ã™ã‚‹æŠ•ç¨¿ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚</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> + <style type="stylus"> + :scope + display block + background #fff - > .loading - padding 64px 0 + > .loading + padding 64px 0 - > .empty - display block - margin 0 auto - padding 32px - max-width 400px - text-align center - color #999 + > .empty + display block + margin 0 auto + padding 32px + max-width 400px + text-align center + color #999 - > i - display block - margin-bottom 16px - font-size 3em - color #ccc + > i + display block + margin-bottom 16px + font-size 3em + color #ccc -script. - @mixin \api - @mixin \get-post-summary + </style> + <script> + @mixin \api + @mixin \get-post-summary - @query = @opts.query - @is-loading = true - @is-empty = false - @more-loading = false - @page = 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 + @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 + @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 \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! + @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! - @api \posts/search do - query: @query - page: @page + 1 - .then (posts) ~> - @more-loading = false - @page++ + @more = ~> + if @more-loading or @is-loading or @timeline.posts.length == 0 + return + @more-loading = true @update! - @refs.timeline.prepend-posts posts - .catch (err) ~> - console.error err + @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! + @on-scroll = ~> + current = window.scroll-y + window.inner-height + if current > document.body.offset-height - 16 # éŠã³ + @more! + </script> +</mk-search-posts> diff --git a/src/web/app/desktop/tags/search.tag b/src/web/app/desktop/tags/search.tag index aec426ac7940a30d8601f1339fa22424830a27f8..1a9703016d8bad739cfc6bcea3d4af172de4ea61 100644 --- a/src/web/app/desktop/tags/search.tag +++ b/src/web/app/desktop/tags/search.tag @@ -1,28 +1,32 @@ -mk-search - header - h1 { query } - mk-search-posts@posts(query={ query }) +<mk-search> + <header> + <h1>{ query }</h1> + </header> + <mk-search-posts ref="posts" query="{ query }"></mk-search-posts> + <style type="stylus"> + :scope + display block + padding-bottom 32px -style. - display block - padding-bottom 32px + > header + width 100% + max-width 600px + margin 0 auto + color #555 - > header - width 100% - max-width 600px - margin 0 auto - color #555 + > mk-search-posts + max-width 600px + margin 0 auto + border solid 1px rgba(0, 0, 0, 0.075) + border-radius 6px + overflow hidden - > mk-search-posts - max-width 600px - margin 0 auto - border solid 1px rgba(0, 0, 0, 0.075) - border-radius 6px - overflow hidden + </style> + <script> + @query = @opts.query -script. - @query = @opts.query - - @on \mount ~> - @refs.posts.on \loaded ~> - @trigger \loaded + @on \mount ~> + @refs.posts.on \loaded ~> + @trigger \loaded + </script> +</mk-search> diff --git a/src/web/app/desktop/tags/select-file-from-drive-window.tag b/src/web/app/desktop/tags/select-file-from-drive-window.tag index 5042944837c858ed32ead215401c3a168bb8e47d..3293abb2209aeb3d0525d52898ff9a0bce2840e2 100644 --- a/src/web/app/desktop/tags/select-file-from-drive-window.tag +++ b/src/web/app/desktop/tags/select-file-from-drive-window.tag @@ -1,160 +1,161 @@ -mk-select-file-from-drive-window - mk-window@window(is-modal={ true }, width={ '800px' }, height={ '500px' }) - <yield to="header"> - mk-raw(content={ parent.title }) - span.count(if={ parent.multiple && parent.file.length > 0 }) ({ parent.file.length }ファイルé¸æŠžä¸) - </yield> - <yield to="content"> - mk-drive-browser@browser(multiple={ parent.multiple }) - div - button.upload(title='PCã‹ã‚‰ãƒ‰ãƒ©ã‚¤ãƒ–ã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’アップãƒãƒ¼ãƒ‰', onclick={ parent.upload }): i.fa.fa-upload - button.cancel(onclick={ parent.close }) ã‚ャンセル - button.ok(disabled={ parent.multiple && parent.file.length == 0 }, onclick={ parent.ok }) 決定 - </yield> - -style. - > mk-window - [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 +<mk-select-file-from-drive-window> + <mk-window ref="window" is-modal="{ true }" width="{ '800px' }" height="{ '500px' }"><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> +<yield to="content"> + <mk-drive-browser ref="browser" multiple="{ parent.multiple }"></mk-drive-browser> + <div> + <button class="upload" title="PCã‹ã‚‰ãƒ‰ãƒ©ã‚¤ãƒ–ã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’アップãƒãƒ¼ãƒ‰" onclick="{ parent.upload }"><i class="fa fa-upload"></i></button> + <button class="cancel" onclick="{ parent.close }">ã‚ャンセル</button> + <button class="ok" disabled="{ parent.multiple && parent.file.length == 0 }" onclick="{ parent.ok }">決定</button> + </div></yield> + </mk-window> + <style type="stylus"> + :scope + > mk-window + [data-yield='header'] + > mk-raw + > i + margin-right 4px + + .count + margin-left 8px opacity 0.7 - cursor default - - .ok - 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%) - - &: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 - - .cancel - right 148px - color #888 - background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) - border solid 1px #e2e2e2 - - &:hover - background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) - border-color #dcdcdc - &:active - background #ececec - border-color #dcdcdc + [data-yield='content'] + > mk-drive-browser + height calc(100% - 72px) -script. - @file = [] + > div + height 72px + background lighten($theme-color, 95%) - @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! + .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 + cursor default + + .ok + 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%) + + &: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 + + .cancel + right 148px + color #888 + background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%) + border solid 1px #e2e2e2 + + &:hover + background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%) + 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> diff --git a/src/web/app/desktop/tags/set-avatar-suggestion.tag b/src/web/app/desktop/tags/set-avatar-suggestion.tag index 68c9c310dfe3f04d75812ac8129be965cef0d172..a8fc2a69ee7bbea4d8e9fb78179e2ac0c9bdbe6b 100644 --- a/src/web/app/desktop/tags/set-avatar-suggestion.tag +++ b/src/web/app/desktop/tags/set-avatar-suggestion.tag @@ -1,44 +1,46 @@ -mk-set-avatar-suggestion(onclick={ set }) - p - b ã‚¢ãƒã‚¿ãƒ¼ã‚’è¨å®š - | ã—ã¦ã¿ã¾ã›ã‚“ã‹ï¼Ÿ - button(onclick={ close }): i.fa.fa-times - -style. - display block - cursor pointer - color #fff - background #a8cad0 - - &:hover - background #70abb5 - - > p - display block - margin 0 auto - padding 8px - max-width 1024px - - > a - font-weight bold +<mk-set-avatar-suggestion onclick="{ set }"> + <p><b>ã‚¢ãƒã‚¿ãƒ¼ã‚’è¨å®š</b>ã—ã¦ã¿ã¾ã›ã‚“ã‹ï¼Ÿ + <button onclick="{ close }"><i class="fa fa-times"></i></button> + </p> + <style type="stylus"> + :scope + display block + cursor pointer color #fff - - > button - position absolute - top 0 - right 0 - padding 8px - color #fff - -script. - @mixin \i - @mixin \update-avatar - - @set = ~> - @update-avatar @I, (i) ~> - @update-i i - - @close = (e) ~> - e.prevent-default! - e.stop-propagation! - @unmount! + background #a8cad0 + + &:hover + background #70abb5 + + > p + display block + margin 0 auto + padding 8px + max-width 1024px + + > a + font-weight bold + color #fff + + > button + position absolute + top 0 + 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> diff --git a/src/web/app/desktop/tags/set-banner-suggestion.tag b/src/web/app/desktop/tags/set-banner-suggestion.tag index bff0385803ff956a9ef69ad9054dc53629c23497..ab4bbda0474a5b84bd0c050e6d9871ef6a8c8998 100644 --- a/src/web/app/desktop/tags/set-banner-suggestion.tag +++ b/src/web/app/desktop/tags/set-banner-suggestion.tag @@ -1,44 +1,46 @@ -mk-set-banner-suggestion(onclick={ set }) - p - b ãƒãƒŠãƒ¼ã‚’è¨å®š - | ã—ã¦ã¿ã¾ã›ã‚“ã‹ï¼Ÿ - button(onclick={ close }): i.fa.fa-times - -style. - display block - cursor pointer - color #fff - background #a8cad0 - - &:hover - background #70abb5 - - > p - display block - margin 0 auto - padding 8px - max-width 1024px - - > a - font-weight bold +<mk-set-banner-suggestion onclick="{ set }"> + <p><b>ãƒãƒŠãƒ¼ã‚’è¨å®š</b>ã—ã¦ã¿ã¾ã›ã‚“ã‹ï¼Ÿ + <button onclick="{ close }"><i class="fa fa-times"></i></button> + </p> + <style type="stylus"> + :scope + display block + cursor pointer color #fff - - > button - position absolute - top 0 - right 0 - padding 8px - color #fff - -script. - @mixin \i - @mixin \update-banner - - @set = ~> - @update-banner @I, (i) ~> - @update-i i - - @close = (e) ~> - e.prevent-default! - e.stop-propagation! - @unmount! + background #a8cad0 + + &:hover + background #70abb5 + + > p + display block + margin 0 auto + padding 8px + max-width 1024px + + > a + font-weight bold + color #fff + + > button + position absolute + top 0 + 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> diff --git a/src/web/app/desktop/tags/settings-window.tag b/src/web/app/desktop/tags/settings-window.tag index e25984871827e2d4d3057386ebaf4cc4cf0ffd0f..6013f89673c8dfe917245da8fa72abc16f4a393b 100644 --- a/src/web/app/desktop/tags/settings-window.tag +++ b/src/web/app/desktop/tags/settings-window.tag @@ -1,26 +1,25 @@ -mk-settings-window - mk-window@window(is-modal={ true }, width={ '700px' }, height={ '550px' }) - <yield to="header"> - i.fa.fa-cog - | è¨å®š - </yield> - <yield to="content"> - mk-settings - </yield> +<mk-settings-window> + <mk-window ref="window" is-modal="{ true }" width="{ '700px' }" height="{ '550px' }"><yield to="header"><i class="fa fa-cog"></i>è¨å®š</yield> +<yield to="content"> + <mk-settings></mk-settings></yield> + </mk-window> + <style type="stylus"> + :scope + > mk-window + [data-yield='header'] + > i + margin-right 4px -style. - > mk-window - [data-yield='header'] - > i - margin-right 4px + [data-yield='content'] + overflow auto - [data-yield='content'] - overflow auto + </style> + <script> + @on \mount ~> + @refs.window.on \closed ~> + @unmount! -script. - @on \mount ~> - @refs.window.on \closed ~> - @unmount! - - @close = ~> - @refs.window.close! + @close = ~> + @refs.window.close! + </script> +</mk-settings-window> diff --git a/src/web/app/desktop/tags/settings.tag b/src/web/app/desktop/tags/settings.tag index ac47fbf792d54f030f4227074c218b796a83d143..7e7811df21303a3cd5c7222d4577ca15f2106d2e 100644 --- a/src/web/app/desktop/tags/settings.tag +++ b/src/web/app/desktop/tags/settings.tag @@ -1,271 +1,266 @@ -mk-settings - div.nav - p(class={ active: page == 'account' }, onmousedown={ set-page.bind(null, 'account') }) - i.fa.fa-fw.fa-user - | アカウント - p(class={ active: page == 'web' }, onmousedown={ set-page.bind(null, 'web') }) - i.fa.fa-fw.fa-desktop - | Web - p(class={ active: page == 'notification' }, onmousedown={ set-page.bind(null, 'notification') }) - i.fa.fa-fw.fa-bell-o - | 通知 - p(class={ active: page == 'drive' }, onmousedown={ set-page.bind(null, 'drive') }) - i.fa.fa-fw.fa-cloud - | ドライブ - p(class={ active: page == 'apps' }, onmousedown={ set-page.bind(null, 'apps') }) - i.fa.fa-fw.fa-puzzle-piece - | アプリ - p(class={ active: page == 'signin' }, onmousedown={ set-page.bind(null, 'signin') }) - i.fa.fa-fw.fa-sign-in - | ãƒã‚°ã‚¤ãƒ³å±¥æ´ - p(class={ active: page == 'password' }, onmousedown={ set-page.bind(null, 'password') }) - i.fa.fa-fw.fa-unlock-alt - | パスワード - p(class={ active: page == 'api' }, onmousedown={ set-page.bind(null, 'api') }) - i.fa.fa-fw.fa-key - | API - - div.pages - section.account(show={ page == 'account' }) - h1 アカウント - label.avatar - p ã‚¢ãƒã‚¿ãƒ¼ - img.avatar(src={ I.avatar_url + '?thumbnail&size=64' }, alt='avatar') - button.style-normal(onclick={ avatar }) ç”»åƒã‚’é¸æŠž - label - p åå‰ - input@account-name(type='text', value={ I.name }) - label - p å ´æ‰€ - input@account-location(type='text', value={ I.location }) - label - p 自己紹介 - textarea@account-bio { I.bio } - label - p 誕生日 - input@account-birthday(type='date', value={ I.birthday }) - button.style-primary(onclick={ update-account }) ä¿å˜ - - section.web(show={ page == 'web' }) - h1 デザイン - label - p å£ç´™ - button.style-normal(onclick={ wallpaper }) ç”»åƒã‚’é¸æŠž - section.web(show={ page == 'web' }) - h1 ãã®ä»– - label.checkbox - input(type='checkbox', checked={ I.data.cache }, onclick={ update-cache }) - p èªã¿è¾¼ã¿ã‚’高速化ã™ã‚‹ - p API通信時ã«æ–°é®®ãªãƒ¦ãƒ¼ã‚¶ãƒ¼æƒ…å ±ã‚’ã‚ャッシュã™ã‚‹ã“ã¨ã§ãƒ•ã‚§ãƒƒãƒã®ã‚ªãƒ¼ãƒãƒ¼ãƒ˜ãƒƒãƒ‰ã‚’ç„¡ãã—ã¾ã™ã€‚(実験的) - label.checkbox - input(type='checkbox', checked={ I.data.debug }, onclick={ update-debug }) - p 開発者モード - p デãƒãƒƒã‚°ç‰ã®é–‹ç™ºè€…モードを有効ã«ã—ã¾ã™ã€‚ - label.checkbox - input(type='checkbox', checked={ I.data.nya }, onclick={ update-nya }) - p <i>ãª</i>ã‚’<i>ã«ã‚ƒ</i>ã«å¤‰æ›ã™ã‚‹ - p 攻撃的ãªæŠ•ç¨¿ãŒå¤šå°‘和らãå¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ - - section.signin(show={ page == 'signin' }) - h1 ãƒã‚°ã‚¤ãƒ³å±¥æ´ - mk-signin-history - - section.api(show={ page == 'api' }) - h1 API - p - | Token: - code { I.token } - 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 +<mk-settings> + <div class="nav"> + <p class="{ active: page == 'account' }" onmousedown="{ setPage.bind(null, 'account') }"><i class="fa fa-fw fa-user"></i>アカウント</p> + <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 == 'drive' }" onmousedown="{ setPage.bind(null, 'drive') }"><i class="fa fa-fw fa-cloud"></i>ドライブ</p> + <p class="{ active: page == 'apps' }" onmousedown="{ setPage.bind(null, 'apps') }"><i class="fa fa-fw fa-puzzle-piece"></i>アプリ</p> + <p class="{ active: page == 'signin' }" onmousedown="{ setPage.bind(null, 'signin') }"><i class="fa fa-fw fa-sign-in"></i>ãƒã‚°ã‚¤ãƒ³å±¥æ´</p> + <p class="{ active: page == 'password' }" onmousedown="{ setPage.bind(null, 'password') }"><i class="fa fa-fw fa-unlock-alt"></i>パスワード</p> + <p class="{ active: page == 'api' }" onmousedown="{ setPage.bind(null, 'api') }"><i class="fa fa-fw fa-key"></i>API</p> + </div> + <div class="pages"> + <section class="account" show="{ page == 'account' }"> + <h1>アカウント</h1> + <label class="avatar"> + <p>ã‚¢ãƒã‚¿ãƒ¼</p><img class="avatar" src="{ I.avatar_url + '?thumbnail&size=64' }" alt="avatar"/> + <button class="style-normal" onclick="{ avatar }">ç”»åƒã‚’é¸æŠž</button> + </label> + <label> + <p>åå‰</p> + <input ref="accountName" type="text" value="{ I.name }"/> + </label> + <label> + <p>å ´æ‰€</p> + <input ref="accountLocation" type="text" value="{ I.location }"/> + </label> + <label> + <p>自己紹介</p> + <textarea ref="accountBio">{ I.bio }</textarea> + </label> + <label> + <p>誕生日</p> + <input ref="accountBirthday" type="date" value="{ I.birthday }"/> + </label> + <button class="style-primary" onclick="{ updateAccount }">ä¿å˜</button> + </section> + <section class="web" show="{ page == 'web' }"> + <h1>デザイン</h1> + <label> + <p>å£ç´™</p> + <button class="style-normal" onclick="{ wallpaper }">ç”»åƒã‚’é¸æŠž</button> + </label> + </section> + <section class="web" show="{ page == 'web' }"> + <h1>ãã®ä»–</h1> + <label class="checkbox"> + <input type="checkbox" checked="{ I.data.cache }" onclick="{ updateCache }"/> + <p>èªã¿è¾¼ã¿ã‚’高速化ã™ã‚‹</p> + <p>API通信時ã«æ–°é®®ãªãƒ¦ãƒ¼ã‚¶ãƒ¼æƒ…å ±ã‚’ã‚ャッシュã™ã‚‹ã“ã¨ã§ãƒ•ã‚§ãƒƒãƒã®ã‚ªãƒ¼ãƒãƒ¼ãƒ˜ãƒƒãƒ‰ã‚’ç„¡ãã—ã¾ã™ã€‚(実験的)</p> + </label> + <label class="checkbox"> + <input type="checkbox" checked="{ I.data.debug }" onclick="{ updateDebug }"/> + <p>開発者モード</p> + <p>デãƒãƒƒã‚°ç‰ã®é–‹ç™ºè€…モードを有効ã«ã—ã¾ã™ã€‚</p> + </label> + <label class="checkbox"> + <input type="checkbox" checked="{ I.data.nya }" onclick="{ updateNya }"/> + <p><i>ãª</i>ã‚’<i>ã«ã‚ƒ</i>ã«å¤‰æ›ã™ã‚‹</p> + <p>攻撃的ãªæŠ•ç¨¿ãŒå¤šå°‘和らãå¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</p> + </label> + </section> + <section class="signin" show="{ page == 'signin' }"> + <h1>ãƒã‚°ã‚¤ãƒ³å±¥æ´</h1> + <mk-signin-history></mk-signin-history> + </section> + <section class="api" show="{ page == 'api' }"> + <h1>API</h1> + <p>Token:<code>{ I.token }</code></p> + <p>APIを利用ã™ã‚‹ã«ã¯ã€ä¸Šè¨˜ã®ãƒˆãƒ¼ã‚¯ãƒ³ã‚’「iã€ã¨ã„ã†ã‚ーã§ãƒ‘ラメータã«ä»˜åŠ ã—ã¦ãƒªã‚¯ã‚¨ã‚¹ãƒˆã—ã¾ã™ã€‚</p> + <p>アカウントを乗ã£å–られã¦ã—ã¾ã†å¯èƒ½æ€§ãŒã‚ã‚‹ãŸã‚ã€ã“ã®ãƒˆãƒ¼ã‚¯ãƒ³ã¯ç¬¬ä¸‰è€…ã«æ•™ãˆãªã„ã§ãã ã•ã„(アプリãªã©ã«ã‚‚入力ã—ãªã„ã§ãã ã•ã„)。</p> + <p>万ãŒä¸€ã“ã®ãƒˆãƒ¼ã‚¯ãƒ³ãŒæ¼ã‚ŒãŸã‚Šãã®å¯èƒ½æ€§ãŒã‚ã‚‹å ´åˆã¯ + <button class="regenerate" onclick="{ regenerateToken }">トークンをå†ç”Ÿæˆ</button>ã§ãã¾ã™ã€‚(副作用ã¨ã—ã¦ã€ãƒã‚°ã‚¤ãƒ³ã—ã¦ã„ã‚‹ã™ã¹ã¦ã®ãƒ‡ãƒã‚¤ã‚¹ã§ãƒã‚°ã‚¢ã‚¦ãƒˆãŒç™ºç”Ÿã—ã¾ã™) + </p> + </section> + </div> + <style type="stylus"> + :scope display block - padding 10px 16px - margin 0 - color #666 - cursor pointer - - -ms-user-select none - -moz-user-select none - -webkit-user-select none - user-select none - - transition margin-left 0.2s ease - - > i - margin-right 4px - - &:hover - color #555 - - &.active - margin-left 8px - color $theme-color !important - - > .pages - 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 - margin 0 0 8px 0 - font-weight bold - color #373a3c + 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 - &.checkbox - > input - position absolute - top 0 - left 0 + > p + display block + padding 10px 16px + margin 0 + color #666 + cursor pointer - &:checked + p - color $theme-color + -ms-user-select none + -moz-user-select none + -webkit-user-select none + user-select none - > p - width calc(100% - 32px) - margin 0 0 0 32px - font-weight bold + transition margin-left 0.2s ease - &:last-child - font-weight normal - color #999 + > i + margin-right 4px - &.account - > .general - > .avatar - > img + &:hover + color #555 + + &.active + margin-left 8px + color $theme-color !important + + > .pages + 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 - 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 + clear both + + > p + margin 0 0 8px 0 + font-weight bold + color #373a3c + + &.checkbox + > input + position absolute + top 0 + left 0 + + &: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 - -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! + &: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> diff --git a/src/web/app/desktop/tags/signin-history.tag b/src/web/app/desktop/tags/signin-history.tag index 311f8bfedafedb5f1c53c6d94c2bcfaefe30d436..bd6006965fa4aa8e571cb6c7ee9fb5f92f5d657d 100644 --- a/src/web/app/desktop/tags/signin-history.tag +++ b/src/web/app/desktop/tags/signin-history.tag @@ -1,73 +1,75 @@ -mk-signin-history - div.records(if={ history.length != 0 }) - div(each={ history }) - mk-time(time={ created_at }) - header - i.fa.fa-check(if={ success }) - i.fa.fa-times(if={ !success }) - span.ip { ip } - pre: code { JSON.stringify(headers, null, ' ') } - -style. - display block - - > .records - > div - padding 16px 0 0 0 - border-bottom solid 1px #eee - - > header - - > i - margin-right 8px - - &.fa-check - color #0fda82 - - &.fa-times - color #ff3100 - - > .ip - display inline-block - color #444 - background #f8f8f8 - - > mk-time - position absolute - top 16px - right 0 - color #777 - - > pre - overflow auto - max-height 100px - - > code - white-space pre-wrap - word-break break-all - color #4a535a - -script. - @mixin \api - @mixin \stream - - @history = [] - @fetching = true - - @on \mount ~> - @api \i/signin_history - .then (history) ~> - @history = history - @fetching = false +<mk-signin-history> + <div class="records" if="{ history.length != 0 }"> + <div each="{ history }"> + <mk-time time="{ created_at }"></mk-time> + <header><i class="fa fa-check" if="{ success }"></i><i class="fa fa-times" if="{ !success }"></i><span class="ip">{ ip }</span></header> + <pre><code>{ JSON.stringify(headers, null, ' ') }</code></pre> + </div> + </div> + <style type="stylus"> + :scope + display block + + > .records + > div + padding 16px 0 0 0 + border-bottom solid 1px #eee + + > header + + > i + margin-right 8px + + &.fa-check + color #0fda82 + + &.fa-times + color #ff3100 + + > .ip + display inline-block + color #444 + background #f8f8f8 + + > mk-time + position absolute + top 16px + right 0 + color #777 + + > pre + overflow auto + max-height 100px + + > code + white-space pre-wrap + word-break break-all + color #4a535a + + </style> + <script> + @mixin \api + @mixin \stream + + @history = [] + @fetching = true + + @on \mount ~> + @api \i/signin_history + .then (history) ~> + @history = history + @fetching = false + @update! + .catch (err) ~> + console.error err + + @stream.on \signin @on-signin + + @on \unmount ~> + @stream.off \signin @on-signin + + @on-signin = (signin) ~> + @history.unshift signin @update! - .catch (err) ~> - console.error err - - @stream.on \signin @on-signin - - @on \unmount ~> - @stream.off \signin @on-signin - - @on-signin = (signin) ~> - @history.unshift signin - @update! + </script> +</mk-signin-history> diff --git a/src/web/app/desktop/tags/stream-indicator.tag b/src/web/app/desktop/tags/stream-indicator.tag index 2eb5889ca6f8c7bb17bf8d20ca0af49275b5d5ca..4046f5fec43d850614027529199f571c1df6a3fe 100644 --- a/src/web/app/desktop/tags/stream-indicator.tag +++ b/src/web/app/desktop/tags/stream-indicator.tag @@ -1,59 +1,54 @@ -mk-stream-indicator - p(if={ state == 'initializing' }) - i.fa.fa-spinner.fa-spin - span - | æŽ¥ç¶šä¸ - mk-ellipsis - p(if={ state == 'reconnecting' }) - i.fa.fa-spinner.fa-spin - span - | 切æ–ã•ã‚Œã¾ã—ãŸ æŽ¥ç¶šä¸ - mk-ellipsis - p(if={ state == 'connected' }) - i.fa.fa-check - span 接続完了 - -style. - display block - pointer-events none - 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 - display block - margin 0 - - > i - margin-right 0.25em - -script. - @mixin \stream - - @on \before-mount ~> - @state = @get-stream-state! - - if @state == \connected - @root.style.opacity = 0 - - @stream-state-ev.on \connected ~> - @state = @get-stream-state! - @update! - set-timeout ~> +<mk-stream-indicator> + <p if="{ state == 'initializing' }"><i class="fa fa-spinner fa-spin"></i><span>æŽ¥ç¶šä¸ + <mk-ellipsis></mk-ellipsis></span></p> + <p if="{ state == 'reconnecting' }"><i class="fa fa-spinner fa-spin"></i><span>切æ–ã•ã‚Œã¾ã—ãŸ æŽ¥ç¶šä¸ + <mk-ellipsis></mk-ellipsis></span></p> + <p if="{ state == 'connected' }"><i class="fa fa-check"></i><span>接続完了</span></p> + <style type="stylus"> + :scope + display block + pointer-events none + 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 + display block + margin 0 + + > i + margin-right 0.25em + + </style> + <script> + @mixin \stream + + @on \before-mount ~> + @state = @get-stream-state! + + if @state == \connected + @root.style.opacity = 0 + + @stream-state-ev.on \connected ~> + @state = @get-stream-state! + @update! + set-timeout ~> + Velocity @root, { + opacity: 0 + } 200ms \linear + , 1000ms + + @stream-state-ev.on \closed ~> + @state = @get-stream-state! + @update! Velocity @root, { - opacity: 0 - } 200ms \linear - , 1000ms - - @stream-state-ev.on \closed ~> - @state = @get-stream-state! - @update! - Velocity @root, { - opacity: 1 - } 0ms + opacity: 1 + } 0ms + </script> +</mk-stream-indicator> diff --git a/src/web/app/desktop/tags/sub-post-content.tag b/src/web/app/desktop/tags/sub-post-content.tag index 976a6f398fc7e6d55309de85d808979ae8fc69ca..5b4497fda6a84ce5b17a2b919824df0f034271bc 100644 --- a/src/web/app/desktop/tags/sub-post-content.tag +++ b/src/web/app/desktop/tags/sub-post-content.tag @@ -1,37 +1,38 @@ -mk-sub-post-content - div.body - a.reply(if={ post.reply_to_id }): i.fa.fa-reply - span@text - a.quote(if={ post.repost_id }, href={ '/post:' + post.repost_id }) RP: ... - details(if={ post.media }) - summary ({ post.media.length }æžšã®ç”»åƒ) - mk-images-viewer(images={ post.media }) +<mk-sub-post-content> + <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> + <details if="{ post.media }"> + <summary>({ post.media.length }æžšã®ç”»åƒ)</summary> + <mk-images-viewer images="{ post.media }"></mk-images-viewer> + </details> + <style type="stylus"> + :scope + display block + word-wrap break-word -style. - display block - word-wrap break-word + > .body + > .reply + margin-right 6px + color #717171 - > .body - > .reply - margin-right 6px - color #717171 + > .quote + margin-left 4px + font-style oblique + color #a0bf46 - > .quote - margin-left 4px - font-style oblique - color #a0bf46 + </style> + <script> + @mixin \text + @mixin \user-preview -script. - @mixin \text - @mixin \user-preview + @post = @opts.post - @post = @opts.post + @on \mount ~> + if @post.text? + tokens = @analyze @post.text + @refs.text.innerHTML = @compile tokens, false - @on \mount ~> - if @post.text? - tokens = @analyze @post.text - @refs.text.innerHTML = @compile tokens, false - - @refs.text.children.for-each (e) ~> - if e.tag-name == \MK-URL - riot.mount e + @refs.text.children.for-each (e) ~> + if e.tag-name == \MK-URL + riot.mount e + </script> +</mk-sub-post-content> diff --git a/src/web/app/desktop/tags/timeline-post-sub.tag b/src/web/app/desktop/tags/timeline-post-sub.tag index 39b1ad7f7119cdeaf13140bf6347d7f645e09127..a9a13e9f9c63ce962e2b27e5e8e9e91258ca42e9 100644 --- a/src/web/app/desktop/tags/timeline-post-sub.tag +++ b/src/web/app/desktop/tags/timeline-post-sub.tag @@ -1,95 +1,99 @@ -mk-timeline-post-sub(title={ title }) - article - a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }) - img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ post.user_id }) - div.main - header - a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id }) - | { post.user.name } - span.username - | @{ post.user.username } - a.created-at(href={ CONFIG.url + '/' + post.user.username + '/' + post.id }) - mk-time(time={ post.created_at }) - div.body - mk-sub-post-content.text(post={ post }) - -script. - @mixin \date-stringify - @mixin \user-preview - - @post = @opts.post - - @title = @date-stringify @post.created_at - -style. - display block - margin 0 - padding 0 - font-size 0.9em - - > article - padding 16px - - &:after - content "" +<mk-timeline-post-sub title="{ title }"> + <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> + <div class="main"> + <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 }"> + <mk-time time="{ post.created_at }"></mk-time></a></header> + <div class="body"> + <mk-sub-post-content class="text" post="{ post }"></mk-sub-post-content> + </div> + </div> + </article> + <script> + @mixin \date-stringify + @mixin \user-preview + + @post = @opts.post + + @title = @date-stringify @post.created_at + + </script> + <style type="stylus"> + :scope display block - clear both - - &:hover - > .main > footer > button - color #888 - - > .avatar-anchor - display block - float left - margin 0 14px 0 0 - - > .avatar - display block - width 52px - height 52px - margin 0 - border-radius 8px - vertical-align bottom - - > .main - float left - width calc(100% - 66px) - - > header - margin-bottom 4px - white-space nowrap - line-height 21px - - > .name - display inline - margin 0 - padding 0 - color #607073 - 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 #d1d8da - - > .created-at - position absolute - top 0 - right 0 - color #b2b8bb - - > .body - - > .text - cursor default - margin 0 - padding 0 - font-size 1.1em - color #717171 + margin 0 + padding 0 + font-size 0.9em + + > article + padding 16px + + &:after + content "" + display block + clear both + + &:hover + > .main > footer > button + color #888 + + > .avatar-anchor + display block + float left + margin 0 14px 0 0 + + > .avatar + display block + width 52px + height 52px + margin 0 + border-radius 8px + vertical-align bottom + + > .main + float left + width calc(100% - 66px) + + > header + margin-bottom 4px + white-space nowrap + line-height 21px + + > .name + display inline + margin 0 + padding 0 + color #607073 + 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 #d1d8da + + > .created-at + position absolute + top 0 + right 0 + color #b2b8bb + + > .body + + > .text + cursor default + margin 0 + padding 0 + font-size 1.1em + color #717171 + + + + + + </style> +</mk-timeline-post-sub> diff --git a/src/web/app/desktop/tags/timeline-post.tag b/src/web/app/desktop/tags/timeline-post.tag index 8b90f0d013c91e12f6d21988d71d5b7e40364d58..77d695c365a3d7b5fcff3a5de3df6ff78cfa8684 100644 --- a/src/web/app/desktop/tags/timeline-post.tag +++ b/src/web/app/desktop/tags/timeline-post.tag @@ -1,376 +1,332 @@ -mk-timeline-post(tabindex='-1', title={ title }, onkeydown={ on-key-down }) - - div.reply-to(if={ p.reply_to }) - mk-timeline-post-sub(post={ p.reply_to }) - - div.repost(if={ is-repost }) - p - 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') - i.fa.fa-retweet - a.name(href={ CONFIG.url + '/' + post.user.username }, data-user-preview={ post.user_id }) { post.user.name } - | ãŒRepost - mk-time(time={ post.created_at }) - - article - a.avatar-anchor(href={ CONFIG.url + '/' + p.user.username }) - img.avatar(src={ p.user.avatar_url + '?thumbnail&size=64' }, alt='avatar', data-user-preview={ p.user.id }) - div.main - header - a.name(href={ CONFIG.url + '/' + p.user.username }, data-user-preview={ p.user.id }) - | { p.user.name } - span.username - | @{ p.user.username } - a.created-at(href={ url }) - mk-time(time={ p.created_at }) - div.body - div.text - a.reply(if={ p.reply_to }): i.fa.fa-reply - span@text - a.quote(if={ p.repost != null }) RP: - div.media(if={ p.media }) - mk-images-viewer(images={ p.media }) - div.repost(if={ p.repost }) - i.fa.fa-quote-right.fa-flip-horizontal - mk-post-preview.repost(post={ p.repost }) - footer - button(onclick={ reply }, title='返信') - i.fa.fa-reply - p.count(if={ p.replies_count > 0 }) { p.replies_count } - button(onclick={ repost }, title='Repost') - i.fa.fa-retweet - p.count(if={ p.repost_count > 0 }) { p.repost_count } - button(class={ liked: p.is_liked }, onclick={ like }, title='善哉') - 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 +<mk-timeline-post tabindex="-1" title="{ title }" onkeydown="{ onKeyDown }"> + <div class="reply-to" if="{ p.reply_to }"> + <mk-timeline-post-sub post="{ p.reply_to }"></mk-timeline-post-sub> + </div> + <div class="repost" if="{ isRepost }"> + <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> + <mk-time time="{ post.created_at }"></mk-time> + </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 class="main"> + <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="{ p.created_at }"></mk-time></a></header> + <div class="body"> + <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> + <div class="media" if="{ p.media }"> + <mk-images-viewer images="{ p.media }"></mk-images-viewer> + </div> + <div class="repost" if="{ p.repost }"><i class="fa fa-quote-right fa-flip-horizontal"></i> + <mk-post-preview class="repost" post="{ p.repost }"></mk-post-preview> + </div> + </div> + <footer> + <button onclick="{ reply }" title="返信"><i class="fa fa-reply"></i> + <p class="count" if="{ p.replies_count > 0 }">{ p.replies_count }</p> + </button> + <button onclick="{ repost }" title="Repost"><i class="fa fa-retweet"></i> + <p class="count" if="{ p.repost_count > 0 }">{ p.repost_count }</p> + </button> + <button class="{ liked: p.is_liked }" onclick="{ like }" title="善哉"><i class="fa fa-thumbs-o-up"></i> + <p class="count" if="{ p.likes_count > 0 }">{ p.likes_count }</p> + </button> + <button onclick="{ NotImplementedException }"><i class="fa fa-ellipsis-h"></i></button> + <button onclick="{ toggleDetail }" title="詳細"><i class="fa fa-caret-down" if="{ !isDetailOpened }"></i><i class="fa fa-caret-up" if="{ isDetailOpened }"></i></button> + </footer> + </div> + </article> + <div class="detail" if="{ isDetailOpened }"> + <mk-post-status-graph width="462" height="130" post="{ p }"></mk-post-status-graph> + </div> + <style type="stylus"> + :scope + display block margin 0 - padding 16px 32px - line-height 28px - - .avatar-anchor - display inline-block - - .avatar - vertical-align bottom - width 28px - height 28px - margin 0 8px 0 0 - border-radius 6px - - i - margin-right 4px + padding 0 + background #fff - .name - font-weight bold + &:focus + z-index 1 - > 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) + &: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 + padding 16px 32px + line-height 28px - > mk-post-preview - background transparent + .avatar-anchor + display inline-block - > article - padding 28px 32px 18px 32px + .avatar + vertical-align bottom + width 28px + height 28px + margin 0 8px 0 0 + border-radius 6px - &:after - content "" - display block - clear both + i + margin-right 4px - &:hover - > .main > footer > button - color #888 + .name + font-weight bold - > .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 + > mk-time position absolute - top 0 - right 0 + top 16px + right 32px font-size 0.9em - color #c0c0c0 + line-height 28px - > .body + & + article + padding-top 8px - > .text - cursor default - display block - margin 0 - padding 0 - word-wrap break-word - font-size 1.1em - color #717171 + > .reply-to + padding 0 16px + background rgba(0, 0, 0, 0.0125) - mk-url-preview - margin-top 8px - - > .reply - margin-right 8px - color #717171 - - > .quote - margin-left 4px - font-style oblique - color #a0bf46 - - > .media - > img - display block - max-width 100% - - > .repost - margin 8px 0 - - > i:first-child - position absolute - top -8px - left -8px - z-index 1 - color #c0dac6 - font-size 28px - background #fff - - > mk-post-preview - padding 16px - border dashed 1px #c0dac6 - border-radius 8px - - > footer - > button - margin 0 28px 0 0 - padding 0 8px - line-height 32px - font-size 1em - color #ddd + > mk-post-preview background transparent - border none - cursor pointer - &:hover - color #666 + > article + padding 28px 32px 18px 32px - > .count - display inline - margin 0 0 0 8px - color #999 + &:after + content "" + display block + clear both - &.liked - color $theme-color + &:hover + > .main > footer > button + color #888 - &:last-child - position absolute - right 0 - margin 0 + > .avatar-anchor + display block + float left + margin 0 16px 0 0 - > .detail - padding-top 4px - background rgba(0, 0, 0, 0.0125) - -style(theme='dark'). - background #0D0D0D - - > article - - &:hover - > .main > footer > button - color #eee - - > .main - > header - > .left - > .name - color #9e9c98 - - > .username - color #41403f - - > .right - > .time - color #4e4d4b - - > .body - > .text - color #9e9c98 - - > footer - > button - color #9e9c98 - - &:hover - color #fff - - > .count - color #eee - -script. - @mixin \api - @mixin \text - @mixin \date-stringify - @mixin \user-preview - @mixin \NotImplementedException - - @post = @opts.post - @is-repost = @post.repost? and !@post.text? - @p = if @is-repost then @post.repost else @post - - @title = @date-stringify @p.created_at - - @url = CONFIG.url + '/' + @p.user.username + '/' + @p.id - @is-detail-opened = false - - @on \mount ~> - if @p.text? - tokens = if @p._highlight? - then @analyze @p._highlight - 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 - @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! + > .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 + top 0 + right 0 + font-size 0.9em + color #c0c0c0 + + > .body + + > .text + cursor default + display block + margin 0 + padding 0 + word-wrap break-word + font-size 1.1em + color #717171 + + mk-url-preview + margin-top 8px + + > .reply + margin-right 8px + color #717171 + + > .quote + margin-left 4px + font-style oblique + color #a0bf46 + + > .media + > img + display block + max-width 100% + + > .repost + margin 8px 0 + + > i:first-child + position absolute + top -8px + left -8px + z-index 1 + color #c0dac6 + font-size 28px + background #fff + + > mk-post-preview + padding 16px + border dashed 1px #c0dac6 + border-radius 8px + + > footer + > button + margin 0 28px 0 0 + padding 0 8px + line-height 32px + font-size 1em + color #ddd + background transparent + border none + cursor pointer + + &:hover + color #666 + + > .count + display inline + margin 0 0 0 8px + color #999 + + &.liked + color $theme-color + + &:last-child + position absolute + right 0 + margin 0 + + > .detail + padding-top 4px + background rgba(0, 0, 0, 0.0125) + + </style> + <script> + @mixin \api + @mixin \text + @mixin \date-stringify + @mixin \user-preview + @mixin \NotImplementedException + + @post = @opts.post + @is-repost = @post.repost? and !@post.text? + @p = if @is-repost then @post.repost else @post + + @title = @date-stringify @p.created_at + + @url = CONFIG.url + '/' + @p.user.username + '/' + @p.id + @is-detail-opened = false + + @on \mount ~> + if @p.text? + tokens = if @p._highlight? + then @analyze @p._highlight + 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 - 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> diff --git a/src/web/app/desktop/tags/timeline.tag b/src/web/app/desktop/tags/timeline.tag index dfd1b7c14e0496182392f32b34d95b712acd813c..ce6c00d0baebc97a3444aab7d9520ff59ebddc11 100644 --- a/src/web/app/desktop/tags/timeline.tag +++ b/src/web/app/desktop/tags/timeline.tag @@ -1,86 +1,79 @@ -mk-timeline - virtual(each={ post, i in posts }) - mk-timeline-post(post={ post }) - p.date(if={ i != posts.length - 1 && post._date != posts[i + 1]._date }) - span - i.fa.fa-angle-up - | { post._datetext } - span - i.fa.fa-angle-down - | { posts[i + 1]._datetext } - footer(data-yield='footer') - | <yield from="footer"/> - -style. - display block - - > mk-timeline-post - border-bottom solid 1px #eaeaea - - &:first-child - border-top-left-radius 4px - border-top-right-radius 4px - - &:last-of-type - border-bottom none - - > .date - display block - margin 0 - line-height 32px - font-size 14px - text-align center - color #aaa - background #fdfdfd - border-bottom solid 1px #eaeaea - - span - margin 0 16px - - i - margin-right 8px - - > footer - padding 16px - text-align center - color #ccc - border-top solid 1px #eaeaea - border-bottom-left-radius 4px - border-bottom-right-radius 4px - -style(theme='dark'). - > mk-timeline-post - border-bottom-color #222221 +<mk-timeline> + <virtual each="{ post, i in posts }"> + <mk-timeline-post post="{ post }"></mk-timeline-post> + <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> + </virtual> + <footer data-yield="footer"><yield from="footer"/></footer> + <style type="stylus"> + :scope + display block + + > mk-timeline-post + border-bottom solid 1px #eaeaea + + &:first-child + border-top-left-radius 4px + border-top-right-radius 4px + + &:last-of-type + border-bottom none + + > .date + display block + margin 0 + line-height 32px + font-size 14px + text-align center + color #aaa + background #fdfdfd + border-bottom solid 1px #eaeaea + + span + margin 0 16px + + i + margin-right 8px + + > footer + padding 16px + text-align center + color #ccc + border-top solid 1px #eaeaea + border-bottom-left-radius 4px + border-bottom-right-radius 4px + + </style> + <script> + @posts = [] -script. - @posts = [] + @set-posts = (posts) ~> + @posts = posts + @update! - @set-posts = (posts) ~> - @posts = posts - @update! + @prepend-posts = (posts) ~> + posts.for-each (post) ~> + @posts.push post + @update! - @prepend-posts = (posts) ~> - posts.for-each (post) ~> - @posts.push post + @add-post = (post) ~> + @posts.unshift post @update! - @add-post = (post) ~> - @posts.unshift post - @update! - - @clear = ~> - @posts = [] - @update! + @clear = ~> + @posts = [] + @update! - @focus = ~> - @root.children.0.focus! + @focus = ~> + @root.children.0.focus! - @on \update ~> - @posts.for-each (post) ~> - date = (new Date post.created_at).get-date! - month = (new Date post.created_at).get-month! + 1 - post._date = date - post._datetext = month + '月 ' + date + 'æ—¥' + @on \update ~> + @posts.for-each (post) ~> + date = (new Date post.created_at).get-date! + month = (new Date post.created_at).get-month! + 1 + post._date = date + post._datetext = month + '月 ' + date + 'æ—¥' - @tail = ~> - @posts[@posts.length - 1] + @tail = ~> + @posts[@posts.length - 1] + </script> +</mk-timeline> diff --git a/src/web/app/desktop/tags/ui-header-account.tag b/src/web/app/desktop/tags/ui-header-account.tag index ffb1eeec00060d32a74ddf2a29e0b0d67b24af76..47351b52620b213a8d8286c5dee5e51712a64526 100644 --- a/src/web/app/desktop/tags/ui-header-account.tag +++ b/src/web/app/desktop/tags/ui-header-account.tag @@ -1,219 +1,212 @@ -mk-ui-header-account - button.header(data-active={ is-open.toString() }, onclick={ toggle }) - span.username - | { I.username } - i.fa.fa-angle-down(if={ !is-open }) - i.fa.fa-angle-up(if={ is-open }) - img.avatar(src={ I.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.menu(if={ is-open }) - ul - li: a(href={ '/' + I.username }) - i.fa.fa-user - | プãƒãƒ•ã‚£ãƒ¼ãƒ« - i.fa.fa-angle-right - li(onclick={ drive }): p - i.fa.fa-cloud - | ドライブ - i.fa.fa-angle-right - li: a(href='/i>mentions') - i.fa.fa-at - | ã‚ãªãŸå®›ã¦ - i.fa.fa-angle-right - ul - li(onclick={ settings }): p - 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 +<mk-ui-header-account> + <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> + <div class="menu" if="{ isOpen }"> + <ul> + <li><a href="{ '/' + I.username }"><i class="fa fa-user"></i>プãƒãƒ•ã‚£ãƒ¼ãƒ«<i class="fa fa-angle-right"></i></a></li> + <li onclick="{ drive }"> + <p><i class="fa fa-cloud"></i>ドライブ<i class="fa fa-angle-right"></i></p> + </li> + <li><a href="/i>mentions"><i class="fa fa-at"></i>ã‚ãªãŸå®›ã¦<i class="fa fa-angle-right"></i></a></li> + </ul> + <ul> + <li onclick="{ settings }"> + <p><i class="fa fa-cog"></i>è¨å®š<i class="fa fa-angle-right"></i></p> + </li> + </ul> + <ul> + <li onclick="{ signout }"> + <p><i class="fa fa-power-off"></i>サインアウト<i class="fa fa-angle-right"></i></p> + </li> + </ul> + </div> + <style type="stylus"> + :scope display block 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 - 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 + > .header display block margin 0 padding 0 + color #9eaba8 + border none + background transparent + cursor pointer - > a - > p - display block - z-index 1 - padding 0 28px - margin 0 - line-height 40px - color #868C8C - cursor pointer + * + pointer-events none + + &:hover + color darken(#9eaba8, 20%) + + &:active + color darken(#9eaba8, 30%) + + &[data-active='true'] + color darken(#9eaba8, 20%) - * - pointer-events none + > .avatar + $saturate = 150% + filter saturate($saturate) + -webkit-filter saturate($saturate) + -moz-filter saturate($saturate) + -ms-filter saturate($saturate) - > i:first-of-type - margin-right 6px + > .username + display block + 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 + 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 - > i:last-of-type + & + ul + padding-top 10px + border-top solid 1px #eee + + > li display block - position absolute - top 0 - right 8px - z-index 1 - padding 0 20px - font-size 1.2em - line-height 40px - - &:hover, &:active - text-decoration none - background $theme-color - color $theme-color-foreground - -script. - @mixin \i - @mixin \signout - - @is-open = false - - @on \before-unmount ~> - @close! - - @toggle = ~> - if @is-open + margin 0 + padding 0 + + > a + > p + display block + z-index 1 + padding 0 28px + margin 0 + line-height 40px + color #868C8C + cursor pointer + + * + pointer-events none + + > i:first-of-type + margin-right 6px + + > i:last-of-type + display block + position absolute + top 0 + right 8px + z-index 1 + padding 0 20px + font-size 1.2em + line-height 40px + + &:hover, &:active + text-decoration none + background $theme-color + color $theme-color-foreground + + </style> + <script> + @mixin \i + @mixin \signout + + @is-open = false + + @on \before-unmount ~> @close! - else - @open! - @open = ~> - @is-open = true - @update! - all = document.query-selector-all 'body *' - Array.prototype.for-each.call all, (el) ~> - el.add-event-listener \mousedown @mousedown + @toggle = ~> + if @is-open + @close! + else + @open! + + @open = ~> + @is-open = true + @update! + all = document.query-selector-all 'body *' + Array.prototype.for-each.call all, (el) ~> + el.add-event-listener \mousedown @mousedown + + @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 + + @drive = ~> + @close! + riot.mount document.body.append-child document.create-element \mk-drive-browser-window - @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) + @settings = ~> @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 + 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> diff --git a/src/web/app/desktop/tags/ui-header-clock.tag b/src/web/app/desktop/tags/ui-header-clock.tag index 987907a6844f54a8c18972fd9dc67ddf13d4442d..da50d8401faf710f3e0bd63f9f85b74944163dae 100644 --- a/src/web/app/desktop/tags/ui-header-clock.tag +++ b/src/web/app/desktop/tags/ui-header-clock.tag @@ -1,82 +1,87 @@ -mk-ui-header-clock - div.header - time@time - div.content - mk-analog-clock - -style. - display inline-block - overflow visible - - > .header - padding 0 12px - text-align center - font-size 0.5em - - &, * - cursor: default - - &:hover - background #899492 - - & + .content - visibility visible - - > time - color #fff !important - - * - color #fff !important - - &:after - content "" - display block - clear both - - > time - display table-cell - vertical-align middle - height 48px - color #9eaba8 - - > .yyyymmdd - opacity 0.7 - - > .content - visibility hidden - display block - position absolute - top auto - right 0 - z-index 3 - margin 0 - padding 0 - width 256px - background #899492 - -script. - @draw = ~> - now = new Date! - - yyyy = now.get-full-year! - mm = (\0 + (now.get-month! + 1)).slice -2 - dd = (\0 + now.get-date!).slice -2 - yyyymmdd = "<span class='yyyymmdd'>#yyyy/#mm/#dd</span>" - - hh = (\0 + now.get-hours!).slice -2 - mm = (\0 + now.get-minutes!).slice -2 - hhmm = "<span class='hhmm'>#hh:#mm</span>" - - if now.get-seconds! % 2 == 0 - 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 \unmount ~> - clear-interval @clock +<mk-ui-header-clock> + <div class="header"> + <time ref="time"></time> + </div> + <div class="content"> + <mk-analog-clock></mk-analog-clock> + </div> + <style type="stylus"> + :scope + display inline-block + overflow visible + + > .header + padding 0 12px + text-align center + font-size 0.5em + + &, * + cursor: default + + &:hover + background #899492 + + & + .content + visibility visible + + > time + color #fff !important + + * + color #fff !important + + &:after + content "" + display block + clear both + + > time + display table-cell + vertical-align middle + height 48px + color #9eaba8 + + > .yyyymmdd + opacity 0.7 + + > .content + visibility hidden + display block + position absolute + top auto + right 0 + z-index 3 + margin 0 + padding 0 + width 256px + background #899492 + + </style> + <script> + @draw = ~> + now = new Date! + + yyyy = now.get-full-year! + mm = (\0 + (now.get-month! + 1)).slice -2 + dd = (\0 + now.get-date!).slice -2 + yyyymmdd = "<span class='yyyymmdd'>#yyyy/#mm/#dd</span>" + + hh = (\0 + now.get-hours!).slice -2 + mm = (\0 + now.get-minutes!).slice -2 + hhmm = "<span class='hhmm'>#hh:#mm</span>" + + if now.get-seconds! % 2 == 0 + 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 \unmount ~> + clear-interval @clock + </script> +</mk-ui-header-clock> diff --git a/src/web/app/desktop/tags/ui-header-nav.tag b/src/web/app/desktop/tags/ui-header-nav.tag index 153c3137b4c3112d67d5c0a422e6b81a4d56c077..8844307ae9c704c842d54f4432d5ef2c7822223a 100644 --- a/src/web/app/desktop/tags/ui-header-nav.tag +++ b/src/web/app/desktop/tags/ui-header-nav.tag @@ -1,113 +1,113 @@ -mk-ui-header-nav: ul(if={ SIGNIN }) - li.home(class={ active: page == 'home' }): a(href={ CONFIG.url }) - i.fa.fa-home - p ホーム- li.messaging: a(onclick={ messaging }) - i.fa.fa-comments - p メッセージ - i.fa.fa-circle(if={ has-unread-messaging-messages }) - li.info: a(href='https://twitter.com/misskey_xyz', target='_blank') - i.fa.fa-info - p ãŠçŸ¥ã‚‰ã› - li.tv: a(href='https://misskey.tk', target='_blank') - 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 +<mk-ui-header-nav> + <ul if="{ SIGNIN }"> + <li class="home { active: page == 'home' }"><a href="{ CONFIG.url }"><i class="fa fa-home"></i> + <p>ホーム</p></a></li> + <li class="messaging"><a onclick="{ messaging }"><i class="fa fa-comments"></i> + <p>メッセージ</p><i class="fa fa-circle" if="{ hasUnreadMessagingMessages }"></i></a></li> + <li class="info"><a href="https://twitter.com/misskey_xyz" target="_blank"><i class="fa fa-info"></i> + <p>ãŠçŸ¥ã‚‰ã›</p></a></li> + <li class="tv"><a href="https://misskey.tk" target="_blank"><i class="fa fa-television"></i> + <p>MisskeyTVâ„¢</p></a></li> + <style type="stylus"> + :scope display inline-block - z-index 1 - height 100% - padding 0 24px - font-size 1em - font-variant small-caps - color #9eaba8 - text-decoration none - transition none - cursor pointer - - * - pointer-events none - - &: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 - - @media (max-width 1100px) - display none - - @media (max-width 700px) - padding 0 12px - -script. - @mixin \i - @mixin \api - @mixin \stream - - @page = @opts.page + margin 0 + padding 0 + line-height 3rem + vertical-align top - @on \mount ~> - @stream.on \read_all_messaging_messages @on-read-all-messaging-messages - @stream.on \unread_messaging_message @on-unread-messaging-message + > 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 + z-index 1 + height 100% + padding 0 24px + font-size 1em + font-variant small-caps + color #9eaba8 + text-decoration none + transition none + cursor pointer + + * + pointer-events none + + &: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 + + @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! - # Fetch count of unread messaging messages - @api \messaging/unread - .then (count) ~> - if count.count > 0 + @on-unread-messaging-message = ~> @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 - @update! - - @messaging = ~> - riot.mount document.body.append-child document.create-element \mk-messaging-window + @messaging = ~> + riot.mount document.body.append-child document.create-element \mk-messaging-window + </script> + </ul> +</mk-ui-header-nav> diff --git a/src/web/app/desktop/tags/ui-header-notifications.tag b/src/web/app/desktop/tags/ui-header-notifications.tag index 495aad5004ec3468dc14220d50c87aead9226e81..05d4f4c2cd36b469dbe68b7fda76e3b85fc41964 100644 --- a/src/web/app/desktop/tags/ui-header-notifications.tag +++ b/src/web/app/desktop/tags/ui-header-notifications.tag @@ -1,111 +1,114 @@ -mk-ui-header-notifications - button.header(data-active={ is-open }, onclick={ toggle }) - i.fa.fa-bell-o - div.notifications(if={ is-open }) - mk-notifications - -style. - 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 +<mk-ui-header-notifications> + <button class="header" data-active="{ isOpen }" onclick="{ toggle }"><i class="fa fa-bell-o"></i></button> + <div class="notifications" if="{ isOpen }"> + <mk-notifications></mk-notifications> + </div> + <style type="stylus"> + :scope 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 - -script. - @is-open = false - - @toggle = ~> - if @is-open - @close! - else - @open! - - @open = ~> - @is-open = true - @update! - all = document.query-selector-all 'body *' - Array.prototype.for-each.call all, (el) ~> - el.add-event-listener \mousedown @mousedown - - @close = ~> + 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 + 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 - @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 + + @toggle = ~> + if @is-open + @close! + else + @open! + + @open = ~> + @is-open = true + @update! + all = document.query-selector-all 'body *' + Array.prototype.for-each.call all, (el) ~> + el.add-event-listener \mousedown @mousedown + + @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> diff --git a/src/web/app/desktop/tags/ui-header-post-button.tag b/src/web/app/desktop/tags/ui-header-post-button.tag index 558c987619b527dbf9b6d4de1b706a30112ff5be..79f836408a0b1f1e8091c4cdaa48fec6cbbdd22f 100644 --- a/src/web/app/desktop/tags/ui-header-post-button.tag +++ b/src/web/app/desktop/tags/ui-header-post-button.tag @@ -1,39 +1,41 @@ -mk-ui-header-post-button - button(onclick={ post }, title='æ–°è¦æŠ•ç¨¿') - i.fa.fa-pencil-square-o +<mk-ui-header-post-button> + <button onclick="{ post }" title="æ–°è¦æŠ•ç¨¿"><i class="fa fa-pencil-square-o"></i></button> + <style type="stylus"> + :scope + display inline-block + padding 8px + height 100% + vertical-align top -style. - display inline-block - padding 8px - height 100% - vertical-align top + > button + display inline-block + 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 - > button - display inline-block - 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 + * + pointer-events none - * - pointer-events none + &:hover + background lighten($theme-color, 10%) !important - &:hover - background lighten($theme-color, 10%) !important + &:active + background darken($theme-color, 10%) !important + transition background 0s ease - &:active - background darken($theme-color, 10%) !important - transition background 0s ease - -script. - @post = (e) ~> - @parent.parent.open-post-form! + </style> + <script> + @post = (e) ~> + @parent.parent.open-post-form! + </script> +</mk-ui-header-post-button> diff --git a/src/web/app/desktop/tags/ui-header-search.tag b/src/web/app/desktop/tags/ui-header-search.tag index 24e4e44989613890d951dd73f0de0c89d7a4cc61..8803384938747316a52347082d3763afef42740f 100644 --- a/src/web/app/desktop/tags/ui-header-search.tag +++ b/src/web/app/desktop/tags/ui-header-search.tag @@ -1,37 +1,41 @@ -mk-ui-header-search - form.search(onsubmit={ onsubmit }) - input@q(type='search', placeholder!=' 検索') - div.result +<mk-ui-header-search> + <form class="search" onsubmit="{ onsubmit }"> + <input ref="q" type="search" placeholder=" 検索"/> + <div class="result"></div> + </form> + <style type="stylus"> + :scope -style. + > form + display block + float left - > form - display block - float left + > input + user-select text + 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 - user-select text - 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 + color #9eaba8 - &::-webkit-input-placeholder - color #9eaba8 + </style> + <script> + @mixin \page -script. - @mixin \page - - @onsubmit = (e) ~> - e.prevent-default! - @page '/search:' + @refs.q.value + @onsubmit = (e) ~> + e.prevent-default! + @page '/search:' + @refs.q.value + </script> +</mk-ui-header-search> diff --git a/src/web/app/desktop/tags/ui-header.tag b/src/web/app/desktop/tags/ui-header.tag index b02817cd8432e045898089142195eabd67888d29..4ec0ba183a7fc542844c77cccc93258f67b3288e 100644 --- a/src/web/app/desktop/tags/ui-header.tag +++ b/src/web/app/desktop/tags/ui-header.tag @@ -1,85 +1,85 @@ -mk-ui-header - mk-donation(if={ SIGNIN && !I.data.no_donation }) - mk-special-message - div.main - div.backdrop - div.main: div.container - div.left - mk-ui-header-nav(page={ opts.page }) - div.right - mk-ui-header-search - mk-ui-header-account(if={ SIGNIN }) - mk-ui-header-notifications(if={ SIGNIN }) - mk-ui-header-post-button(if={ SIGNIN }) - mk-ui-header-clock - -style. - display block - position fixed - top 0 - z-index 1024 - width 100% - box-shadow 0 1px 1px rgba(0, 0, 0, 0.075) - - > .main - - > .backdrop - position absolute +<mk-ui-header> + <mk-donation if="{ SIGNIN && !I.data.no_donation }"></mk-donation> + <mk-special-message></mk-special-message> + <div class="main"> + <div class="backdrop"></div> + <div class="main"> + <div class="container"> + <div class="left"> + <mk-ui-header-nav page="{ opts.page }"></mk-ui-header-nav> + </div> + <div class="right"> + <mk-ui-header-search></mk-ui-header-search> + <mk-ui-header-account if="{ SIGNIN }"></mk-ui-header-account> + <mk-ui-header-notifications if="{ SIGNIN }"></mk-ui-header-notifications> + <mk-ui-header-post-button if="{ SIGNIN }"></mk-ui-header-post-button> + <mk-ui-header-clock></mk-ui-header-clock> + </div> + </div> + </div> + </div> + <style type="stylus"> + :scope + display block + position fixed top 0 - z-index 1023 + z-index 1024 width 100% - height 48px - backdrop-filter blur(12px) - //background-color rgba(255, 255, 255, 0.75) - background #fff + box-shadow 0 1px 1px rgba(0, 0, 0, 0.075) - &:after - content "" - display block - width 100% - height 48px - background-image url(/_/resources/desktop/header-logo.svg) - background-size 64px - background-position center - background-repeat no-repeat + > .main - > .main - z-index 1024 - margin 0 - padding 0 - background-clip content-box - font-size 0.9rem - user-select none + > .backdrop + position absolute + top 0 + z-index 1023 + width 100% + height 48px + backdrop-filter blur(12px) + //background-color rgba(255, 255, 255, 0.75) + background #fff - > .container - width 100% - max-width 1300px - margin 0 auto + &:after + content "" + display block + width 100% + height 48px + background-image url(/_/resources/desktop/header-logo.svg) + background-size 64px + background-position center + background-repeat no-repeat - &:after - content "" - display block - clear both + > .main + z-index 1024 + margin 0 + padding 0 + background-clip content-box + font-size 0.9rem + user-select none - > .left - float left - height 3rem + > .container + width 100% + max-width 1300px + margin 0 auto - > .right - float right - height 48px + &:after + content "" + display block + clear both - @media (max-width 1100px) - > mk-ui-header-search - display none + > .left + float left + height 3rem -style(theme='dark'). - box-shadow 0 1px 0 #222221 + > .right + float right + height 48px - > .main + @media (max-width 1100px) + > mk-ui-header-search + display none - > .backdrop - background #0D0D0D + </style> -script. - @mixin \i + <script>@mixin \i</script> +</mk-ui-header> diff --git a/src/web/app/desktop/tags/ui-notification.tag b/src/web/app/desktop/tags/ui-notification.tag index 6e5f948b8845cbcec5c14211af75a2590c2d95d4..aacf23cf50642976f247b9ff4f7e8221d7468347 100644 --- a/src/web/app/desktop/tags/ui-notification.tag +++ b/src/web/app/desktop/tags/ui-notification.tag @@ -1,41 +1,44 @@ -mk-ui-notification - p { opts.message } +<mk-ui-notification> + <p>{ opts.message }</p> + <style type="stylus"> + :scope + display block + position fixed + z-index 10000 + top -64px + left 0 + right 0 + margin 0 auto + width 500px + color rgba(#000, 0.6) + background rgba(#fff, 0.9) + border-radius 0 0 8px 8px + box-shadow 0 2px 4px rgba(#000, 0.2) -style. - display block - position fixed - z-index 10000 - top -64px - left 0 - right 0 - margin 0 auto - width 500px - color rgba(#000, 0.6) - background rgba(#fff, 0.9) - border-radius 0 0 8px 8px - box-shadow 0 2px 4px rgba(#000, 0.2) + > p + margin 0 + line-height 64px + text-align center - > p - margin 0 - line-height 64px - text-align center - -script. - @on \mount ~> - Velocity @root, { - top: \0px - } { - duration: 500ms - easing: \ease-out - } - - set-timeout ~> + </style> + <script> + @on \mount ~> Velocity @root, { - top: \-64px + top: \0px } { duration: 500ms easing: \ease-out - complete: ~> - @unmount! } - , 6000ms + + set-timeout ~> + Velocity @root, { + top: \-64px + } { + duration: 500ms + easing: \ease-out + complete: ~> + @unmount! + } + , 6000ms + </script> +</mk-ui-notification> diff --git a/src/web/app/desktop/tags/ui.tag b/src/web/app/desktop/tags/ui.tag index 6bced1f9e4d1cfe06edfe5de77410c6fa26194e8..713db21d919d80f7f511ad7c184b4cf5255b2fc0 100644 --- a/src/web/app/desktop/tags/ui.tag +++ b/src/web/app/desktop/tags/ui.tag @@ -1,37 +1,37 @@ -mk-ui - div.global@global - mk-ui-header@header(page={ opts.page }) - - mk-set-avatar-suggestion(if={ SIGNIN && I.avatar_id == null }) - mk-set-banner-suggestion(if={ SIGNIN && I.banner_id == null }) - - div.content - <yield /> - - mk-stream-indicator - -style. - display block - -script. - @mixin \i - - @open-post-form = ~> - riot.mount document.body.append-child document.create-element \mk-post-form-window - - @set-root-layout = ~> - @root.style.padding-top = @refs.header.root.client-height + \px - - @on \mount ~> - @set-root-layout! - document.add-event-listener \keydown @onkeydown - - @on \unmount ~> - document.remove-event-listener \keydown @onkeydown - - @onkeydown = (e) ~> - tag = e.target.tag-name.to-lower-case! - if tag != \input and tag != \textarea - if e.which == 80 or e.which == 78 # p or n - e.prevent-default! - @open-post-form! +<mk-ui> + <div class="global" ref="global"> + <mk-ui-header ref="header" page="{ opts.page }"></mk-ui-header> + <mk-set-avatar-suggestion if="{ SIGNIN && I.avatar_id == null }"></mk-set-avatar-suggestion> + <mk-set-banner-suggestion if="{ SIGNIN && I.banner_id == null }"></mk-set-banner-suggestion> + <div class="content"><yield /></div> + </div> + <mk-stream-indicator></mk-stream-indicator> + <style type="stylus"> + :scope + display block + + </style> + <script> + @mixin \i + + @open-post-form = ~> + riot.mount document.body.append-child document.create-element \mk-post-form-window + + @set-root-layout = ~> + @root.style.padding-top = @refs.header.root.client-height + \px + + @on \mount ~> + @set-root-layout! + document.add-event-listener \keydown @onkeydown + + @on \unmount ~> + document.remove-event-listener \keydown @onkeydown + + @onkeydown = (e) ~> + tag = e.target.tag-name.to-lower-case! + if tag != \input and tag != \textarea + if e.which == 80 or e.which == 78 # p or n + e.prevent-default! + @open-post-form! + </script> +</mk-ui> diff --git a/src/web/app/desktop/tags/user-followers-window.tag b/src/web/app/desktop/tags/user-followers-window.tag index d18b04446c6e068d056e4791838cd6bc69d98e84..c6899be46b8795427410ef1d7d464a6e00400749 100644 --- a/src/web/app/desktop/tags/user-followers-window.tag +++ b/src/web/app/desktop/tags/user-followers-window.tag @@ -1,22 +1,19 @@ -mk-user-followers-window - mk-window(is-modal={ false }, width={ '400px' }, height={ '550px' }) - <yield to="header"> - img(src={ parent.user.avatar_url + '?thumbnail&size=64' }, alt='') - | { parent.user.name }ã®ãƒ•ã‚©ãƒãƒ¯ãƒ¼ - </yield> - <yield to="content"> - mk-user-followers(user={ parent.user }) - </yield> +<mk-user-followers-window> + <mk-window is-modal="{ false }" width="{ '400px' }" height="{ '550px' }"><yield to="header"><img src="{ parent.user.avatar_url + '?thumbnail&size=64' }" alt=""/>{ parent.user.name }ã®ãƒ•ã‚©ãƒãƒ¯ãƒ¼</yield> +<yield to="content"> + <mk-user-followers user="{ parent.user }"></mk-user-followers></yield> + </mk-window> + <style type="stylus"> + :scope + > mk-window + [data-yield='header'] + > img + display inline-block + vertical-align bottom + height calc(100% - 10px) + margin 5px + border-radius 4px -style. - > mk-window - [data-yield='header'] - > img - display inline-block - vertical-align bottom - height calc(100% - 10px) - margin 5px - border-radius 4px - -script. - @user = @opts.user + </style> + <script>@user = @opts.user</script> +</mk-user-followers-window> diff --git a/src/web/app/desktop/tags/user-followers.tag b/src/web/app/desktop/tags/user-followers.tag index 52f9f43836302e29489a3df19ae94ce1053b173a..9f96b0017715717f4ee7fc582ae9a08fc889e182 100644 --- a/src/web/app/desktop/tags/user-followers.tag +++ b/src/web/app/desktop/tags/user-followers.tag @@ -1,19 +1,22 @@ -mk-user-followers - mk-users-list(fetch={ fetch }, count={ user.followers_count }, you-know-count={ user.followers_you_know_count }, no-users={ 'フォãƒãƒ¯ãƒ¼ã¯ã„ãªã„よã†ã§ã™ã€‚' }) +<mk-user-followers> + <mk-users-list fetch="{ fetch }" count="{ user.followers_count }" you-know-count="{ user.followers_you_know_count }" no-users="{ 'フォãƒãƒ¯ãƒ¼ã¯ã„ãªã„よã†ã§ã™ã€‚' }"></mk-users-list> + <style type="stylus"> + :scope + display block + height 100% -style. - display block - height 100% + </style> + <script> + @mixin \api -script. - @mixin \api + @user = @opts.user - @user = @opts.user - - @fetch = (iknow, limit, cursor, cb) ~> - @api \users/followers do - user_id: @user.id - iknow: iknow - limit: limit - cursor: if cursor? then cursor else undefined - .then cb + @fetch = (iknow, limit, cursor, cb) ~> + @api \users/followers do + user_id: @user.id + iknow: iknow + limit: limit + cursor: if cursor? then cursor else undefined + .then cb + </script> +</mk-user-followers> diff --git a/src/web/app/desktop/tags/user-following-window.tag b/src/web/app/desktop/tags/user-following-window.tag index 91f94f08d36d558acda5c246770d2cfc539f980c..343820d4e0905885a9ac771289e119d5f134d7b7 100644 --- a/src/web/app/desktop/tags/user-following-window.tag +++ b/src/web/app/desktop/tags/user-following-window.tag @@ -1,22 +1,19 @@ -mk-user-following-window - mk-window(is-modal={ false }, width={ '400px' }, height={ '550px' }) - <yield to="header"> - img(src={ parent.user.avatar_url + '?thumbnail&size=64' }, alt='') - | { parent.user.name }ã®ãƒ•ã‚©ãƒãƒ¼ - </yield> - <yield to="content"> - mk-user-following(user={ parent.user }) - </yield> +<mk-user-following-window> + <mk-window is-modal="{ false }" width="{ '400px' }" height="{ '550px' }"><yield to="header"><img src="{ parent.user.avatar_url + '?thumbnail&size=64' }" alt=""/>{ parent.user.name }ã®ãƒ•ã‚©ãƒãƒ¼</yield> +<yield to="content"> + <mk-user-following user="{ parent.user }"></mk-user-following></yield> + </mk-window> + <style type="stylus"> + :scope + > mk-window + [data-yield='header'] + > img + display inline-block + vertical-align bottom + height calc(100% - 10px) + margin 5px + border-radius 4px -style. - > mk-window - [data-yield='header'] - > img - display inline-block - vertical-align bottom - height calc(100% - 10px) - margin 5px - border-radius 4px - -script. - @user = @opts.user + </style> + <script>@user = @opts.user</script> +</mk-user-following-window> diff --git a/src/web/app/desktop/tags/user-following.tag b/src/web/app/desktop/tags/user-following.tag index 0a39f2e4b8bcad1623d4fe8af2ac5332da8f2d65..87b88b6cd25b6fb462909ad2b059e3e738e1c9a0 100644 --- a/src/web/app/desktop/tags/user-following.tag +++ b/src/web/app/desktop/tags/user-following.tag @@ -1,19 +1,22 @@ -mk-user-following - mk-users-list(fetch={ fetch }, count={ user.following_count }, you-know-count={ user.following_you_know_count }, no-users={ 'フォãƒãƒ¼ä¸ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã„ãªã„よã†ã§ã™ã€‚' }) +<mk-user-following> + <mk-users-list fetch="{ fetch }" count="{ user.following_count }" you-know-count="{ user.following_you_know_count }" no-users="{ 'フォãƒãƒ¼ä¸ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã„ãªã„よã†ã§ã™ã€‚' }"></mk-users-list> + <style type="stylus"> + :scope + display block + height 100% -style. - display block - height 100% + </style> + <script> + @mixin \api -script. - @mixin \api + @user = @opts.user - @user = @opts.user - - @fetch = (iknow, limit, cursor, cb) ~> - @api \users/following do - user_id: @user.id - iknow: iknow - limit: limit - cursor: if cursor? then cursor else undefined - .then cb + @fetch = (iknow, limit, cursor, cb) ~> + @api \users/following do + user_id: @user.id + iknow: iknow + limit: limit + cursor: if cursor? then cursor else undefined + .then cb + </script> +</mk-user-following> diff --git a/src/web/app/desktop/tags/user-friends-graph.tag b/src/web/app/desktop/tags/user-friends-graph.tag index 47c3a15613831fcd51603fbe2d3ddb5794f4bed1..13c0bc2c38d363659d22e136366b63507abe6052 100644 --- a/src/web/app/desktop/tags/user-friends-graph.tag +++ b/src/web/app/desktop/tags/user-friends-graph.tag @@ -1,64 +1,67 @@ -mk-user-friends-graph - canvas@canv(width='750', height='250') +<mk-user-friends-graph> + <canvas ref="canv" width="750" height="250"></canvas> + <style type="stylus"> + :scope + display block + width 750px + height 250px -style. - display block - width 750px - height 250px + </style> + <script> + @mixin \api + @mixin \is-promise -script. - @mixin \api - @mixin \is-promise + @user = null + @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user - @user = null - @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user + @on \mount ~> + user <~ @user-promise.then + @user = user + @update! - @on \mount ~> - user <~ @user-promise.then - @user = user - @update! - - @api \aggregation/users/followers do - user_id: @user.id - limit: 30days - .then (followers) ~> - followers = followers.reverse! - - @api \aggregation/users/following do + @api \aggregation/users/followers do user_id: @user.id limit: 30days - .then (following) ~> - following = following.reverse! + .then (followers) ~> + followers = followers.reverse! + + @api \aggregation/users/following do + user_id: @user.id + limit: 30days + .then (following) ~> + following = following.reverse! - new Chart @refs.canv, do - type: \line - data: - labels: following.map (x, i) ~> if i % 3 == 2 then x.date.day + 'æ—¥' else '' - datasets: [ - { - label: \フォãƒãƒ¼ - data: following.map (x) ~> x.count - line-tension: 0 - border-width: 2 - fill: true - background-color: 'rgba(127, 221, 64, 0.2)' - point-background-color: \#fff - point-radius: 4 - point-border-width: 2 - border-color: \#7fdd40 - }, - { - label: \フォãƒãƒ¯ãƒ¼ - data: followers.map (x) ~> x.count - line-tension: 0 - border-width: 2 - fill: true - background-color: 'rgba(255, 99, 132, 0.2)' - point-background-color: \#fff - point-radius: 4 - point-border-width: 2 - border-color: \#FF6384 - } - ] - options: - responsive: false + new Chart @refs.canv, do + type: \line + data: + labels: following.map (x, i) ~> if i % 3 == 2 then x.date.day + 'æ—¥' else '' + datasets: [ + { + label: \フォãƒãƒ¼ + data: following.map (x) ~> x.count + line-tension: 0 + border-width: 2 + fill: true + background-color: 'rgba(127, 221, 64, 0.2)' + point-background-color: \#fff + point-radius: 4 + point-border-width: 2 + border-color: \#7fdd40 + }, + { + label: \フォãƒãƒ¯ãƒ¼ + data: followers.map (x) ~> x.count + line-tension: 0 + border-width: 2 + fill: true + background-color: 'rgba(255, 99, 132, 0.2)' + point-background-color: \#fff + point-radius: 4 + point-border-width: 2 + border-color: \#FF6384 + } + ] + options: + responsive: false + </script> +</mk-user-friends-graph> diff --git a/src/web/app/desktop/tags/user-graphs.tag b/src/web/app/desktop/tags/user-graphs.tag index f7f0fcd5e0c96f572dd76c279d070e64b4cf3ecc..28643cd90be4339c306203df3e6740a3c1fb31d6 100644 --- a/src/web/app/desktop/tags/user-graphs.tag +++ b/src/web/app/desktop/tags/user-graphs.tag @@ -1,36 +1,40 @@ -mk-user-graphs - section - h1 投稿 - mk-user-posts-graph(user={ opts.user }) +<mk-user-graphs> + <section> + <h1>投稿</h1> + <mk-user-posts-graph user="{ opts.user }"></mk-user-posts-graph> + </section> + <section> + <h1>フォãƒãƒ¼/フォãƒãƒ¯ãƒ¼</h1> + <mk-user-friends-graph user="{ opts.user }"></mk-user-friends-graph> + </section> + <section> + <h1>ã„ã„ã</h1> + <mk-user-likes-graph user="{ opts.user }"></mk-user-likes-graph> + </section> + <style type="stylus"> + :scope + display block - section - h1 フォãƒãƒ¼/フォãƒãƒ¯ãƒ¼ - mk-user-friends-graph(user={ opts.user }) + > section + margin 16px 0 + background #fff + border solid 1px rgba(0, 0, 0, 0.1) + border-radius 4px - section - h1 ã„ã„ã - mk-user-likes-graph(user={ opts.user }) + > h1 + margin 0 0 8px 0 + padding 0 16px + line-height 40px + font-size 1em + color #666 + border-bottom solid 1px #eee -style. - display block + > *:not(h1) + margin 0 auto 16px auto - > section - margin 16px 0 - background #fff - border solid 1px rgba(0, 0, 0, 0.1) - border-radius 4px - - > h1 - margin 0 0 8px 0 - padding 0 16px - line-height 40px - font-size 1em - color #666 - border-bottom solid 1px #eee - - > *:not(h1) - margin 0 auto 16px auto - -script. - @on \mount ~> - @trigger \loaded + </style> + <script> + @on \mount ~> + @trigger \loaded + </script> +</mk-user-graphs> diff --git a/src/web/app/desktop/tags/user-header.tag b/src/web/app/desktop/tags/user-header.tag index 5abd79ff1ce79987369b65da3876f4a935310b56..7b4ebfb84701dc36d9acbbee77eb38ca36933f00 100644 --- a/src/web/app/desktop/tags/user-header.tag +++ b/src/web/app/desktop/tags/user-header.tag @@ -1,143 +1,142 @@ -mk-user-header(data-is-dark-background={ user.banner_url != null }) - div.banner@banner(style={ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=1024)' : '' }, onclick={ on-update-banner }) - img.avatar(src={ user.avatar_url + '?thumbnail&size=150' }, alt='avatar') - div.title - p.name(href={ CONFIG.url + '/' + user.username }) { user.name } - p.username @{ user.username } - p.location(if={ user.location }) - i.fa.fa-map-marker - | { user.location } - footer - a(href={ '/' + user.username }) 投稿 - a(href={ '/' + user.username + '/media' }) メディア - a(href={ '/' + user.username + '/graphs' }) グラフ - button(onclick={ NotImplementedException }): i.fa.fa-ellipsis-h - -style. - $footer-height = 58px - - display block - background #fff - - &[data-is-dark-background] - > .banner - background-color #383838 - - > .title - color #fff - background linear-gradient(transparent, rgba(0, 0, 0, 0.7)) - - > .name - text-shadow 0 0 8px #000 - - > .banner - height 280px - background-color #f5f5f5 - background-size cover - background-position center - - > .avatar - display block - position absolute - bottom 16px - left 16px - z-index 2 - width 150px - height 150px - margin 0 - border solid 3px #fff - border-radius 8px - box-shadow 1px 1px 3px rgba(0, 0, 0, 0.2) - - > .title - position absolute - bottom $footer-height - left 0 - width 100% - padding 0 0 8px 195px - color #656565 - font-family '游ゴシック', 'YuGothic', 'ヒラギノ角ゴ ProN W3', 'Hiragino Kaku Gothic ProN', 'Meiryo', 'メイリオ', sans-serif - - > .name - display block - margin 0 - line-height 40px - font-weight bold - font-size 2em - - > .username - > .location - display inline-block - margin 0 16px 0 0 - line-height 20px - opacity 0.8 - - > i - margin-right 4px - - > footer - z-index 1 - height $footer-height - padding-left 195px - background #fff - - > a - display inline-block - margin 0 - width 100px - line-height $footer-height - color #555 - - > button +<mk-user-header data-is-dark-background="{ user.banner_url != null }"> + <div class="banner" ref="banner" style="{ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=1024)' : '' }" onclick="{ onUpdateBanner }"></div><img class="avatar" src="{ user.avatar_url + '?thumbnail&size=150' }" alt="avatar"/> + <div class="title"> + <p class="name" href="{ CONFIG.url + '/' + user.username }">{ user.name }</p> + <p class="username">@{ user.username }</p> + <p class="location" if="{ user.location }"><i class="fa fa-map-marker"></i>{ user.location }</p> + </div> + <footer><a href="{ '/' + user.username }">投稿</a><a href="{ '/' + user.username + '/media' }">メディア</a><a href="{ '/' + user.username + '/graphs' }">グラフ</a> + <button onclick="{ NotImplementedException }"><i class="fa fa-ellipsis-h"></i></button> + </footer> + <style type="stylus"> + :scope + $footer-height = 58px + display block - position absolute - top 0 - right 0 - margin 8px - padding 0 - width $footer-height - 16px - line-height $footer-height - 16px - 2px - font-size 1.2em - color #777 - border solid 1px #eee - border-radius 4px - - &:hover - color #555 - border solid 1px #ddd - -script. - @mixin \i - @mixin \update-banner - @mixin \NotImplementedException - - @user = @opts.user - - @on \mount ~> - window.add-event-listener \load @scroll - window.add-event-listener \scroll @scroll - window.add-event-listener \resize @scroll - - @on \unmount ~> - window.remove-event-listener \load @scroll - window.remove-event-listener \scroll @scroll - window.remove-event-listener \resize @scroll - - @scroll = ~> - top = window.scroll-y - height = 280px - - pos = 50 - ((top / height) * 50) - @refs.banner.style.background-position = 'center ' + pos + '%' - - blur = top / 32 - if blur <= 10 - @refs.banner.style.filter = 'blur(' + blur + 'px)' - - @on-update-banner = ~> - if not @SIGNIN or @I.id != @user.id - return - - @update-banner @I, (i) ~> - @user.banner_url = i.banner_url - @update! + background #fff + + &[data-is-dark-background] + > .banner + background-color #383838 + + > .title + color #fff + background linear-gradient(transparent, rgba(0, 0, 0, 0.7)) + + > .name + text-shadow 0 0 8px #000 + + > .banner + height 280px + background-color #f5f5f5 + background-size cover + background-position center + + > .avatar + display block + position absolute + bottom 16px + left 16px + z-index 2 + width 150px + height 150px + margin 0 + border solid 3px #fff + border-radius 8px + box-shadow 1px 1px 3px rgba(0, 0, 0, 0.2) + + > .title + position absolute + bottom $footer-height + left 0 + width 100% + padding 0 0 8px 195px + color #656565 + font-family '游ゴシック', 'YuGothic', 'ヒラギノ角ゴ ProN W3', 'Hiragino Kaku Gothic ProN', 'Meiryo', 'メイリオ', sans-serif + + > .name + display block + margin 0 + line-height 40px + font-weight bold + font-size 2em + + > .username + > .location + display inline-block + margin 0 16px 0 0 + line-height 20px + opacity 0.8 + + > i + margin-right 4px + + > footer + z-index 1 + height $footer-height + padding-left 195px + background #fff + + > a + display inline-block + margin 0 + width 100px + line-height $footer-height + color #555 + + > button + display block + position absolute + top 0 + right 0 + margin 8px + padding 0 + width $footer-height - 16px + line-height $footer-height - 16px - 2px + font-size 1.2em + color #777 + border solid 1px #eee + border-radius 4px + + &:hover + color #555 + border solid 1px #ddd + + </style> + <script> + @mixin \i + @mixin \update-banner + @mixin \NotImplementedException + + @user = @opts.user + + @on \mount ~> + window.add-event-listener \load @scroll + window.add-event-listener \scroll @scroll + window.add-event-listener \resize @scroll + + @on \unmount ~> + window.remove-event-listener \load @scroll + window.remove-event-listener \scroll @scroll + window.remove-event-listener \resize @scroll + + @scroll = ~> + top = window.scroll-y + height = 280px + + pos = 50 - ((top / height) * 50) + @refs.banner.style.background-position = 'center ' + pos + '%' + + blur = top / 32 + if blur <= 10 + @refs.banner.style.filter = 'blur(' + blur + 'px)' + + @on-update-banner = ~> + if not @SIGNIN or @I.id != @user.id + return + + @update-banner @I, (i) ~> + @user.banner_url = i.banner_url + @update! + </script> +</mk-user-header> diff --git a/src/web/app/desktop/tags/user-home.tag b/src/web/app/desktop/tags/user-home.tag index 4bf0260ff68cd6294a362ed78543e5b499874895..602ce1b9c9c7b7254b27eaec912c39fd60e2398f 100644 --- a/src/web/app/desktop/tags/user-home.tag +++ b/src/web/app/desktop/tags/user-home.tag @@ -1,40 +1,45 @@ -mk-user-home - div.side - mk-user-profile(user={ user }) - mk-user-photos(user={ user }) - main - mk-user-timeline@tl(user={ user }) +<mk-user-home> + <div class="side"> + <mk-user-profile user="{ user }"></mk-user-profile> + <mk-user-photos user="{ user }"></mk-user-photos> + </div> + <main> + <mk-user-timeline ref="tl" user="{ user }"></mk-user-timeline> + </main> + <style type="stylus"> + :scope + display flex + justify-content center -style. - display flex - justify-content center + > * + > * + display block + //border solid 1px #eaeaea + border solid 1px rgba(0, 0, 0, 0.075) + border-radius 6px + overflow hidden - > * - > * - 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 - &:not(:last-child) - margin-bottom 16px + > main + flex 1 1 560px + max-width 560px + margin 0 + padding 16px 0 16px 16px - > main - flex 1 1 560px - max-width 560px - margin 0 - padding 16px 0 16px 16px + > .side + flex 1 1 270px + max-width 270px + margin 0 + padding 16px 0 16px 0 - > .side - flex 1 1 270px - max-width 270px - margin 0 - padding 16px 0 16px 0 + </style> + <script> + @user = @opts.user -script. - @user = @opts.user - - @on \mount ~> - @refs.tl.on \loaded ~> - @trigger \loaded + @on \mount ~> + @refs.tl.on \loaded ~> + @trigger \loaded + </script> +</mk-user-home> diff --git a/src/web/app/desktop/tags/user-likes-graph.tag b/src/web/app/desktop/tags/user-likes-graph.tag index e9d1428713c5f7be0a5e72e44c536d0cf3f64fc5..1c2759a3a16e486bb76e9756bfbb3bc16d953438 100644 --- a/src/web/app/desktop/tags/user-likes-graph.tag +++ b/src/web/app/desktop/tags/user-likes-graph.tag @@ -1,39 +1,42 @@ -mk-user-likes-graph - canvas@canv(width='750', height='250') +<mk-user-likes-graph> + <canvas ref="canv" width="750" height="250"></canvas> + <style type="stylus"> + :scope + display block + width 750px + height 250px -style. - display block - width 750px - height 250px + </style> + <script> + @mixin \api + @mixin \is-promise -script. - @mixin \api - @mixin \is-promise + @user = null + @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user - @user = null - @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user + @on \mount ~> + user <~ @user-promise.then + @user = user + @update! - @on \mount ~> - user <~ @user-promise.then - @user = user - @update! + @api \aggregation/users/like do + user_id: @user.id + limit: 30days + .then (likes) ~> + likes = likes.reverse! - @api \aggregation/users/like do - user_id: @user.id - limit: 30days - .then (likes) ~> - likes = likes.reverse! - - new Chart @refs.canv, do - type: \bar - data: - labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + 'æ—¥' else '' - datasets: [ - { - label: \ã„ã„ãã—ãŸæ•° - data: likes.map (x) ~> x.count - background-color: \#F7796C - } - ] - options: - responsive: false + new Chart @refs.canv, do + type: \bar + data: + labels: likes.map (x, i) ~> if i % 3 == 2 then x.date.day + 'æ—¥' else '' + datasets: [ + { + label: \ã„ã„ãã—ãŸæ•° + data: likes.map (x) ~> x.count + background-color: \#F7796C + } + ] + options: + responsive: false + </script> +</mk-user-likes-graph> diff --git a/src/web/app/desktop/tags/user-photos.tag b/src/web/app/desktop/tags/user-photos.tag index 61a840ee61e295082644ce410dad591bd2c4f31e..eb79113e41e7f6cfd3558bda8a0a27714b8fa155 100644 --- a/src/web/app/desktop/tags/user-photos.tag +++ b/src/web/app/desktop/tags/user-photos.tag @@ -1,85 +1,86 @@ -mk-user-photos - p.title - i.fa.fa-camera - | フォト - p.initializing(if={ initializing }) - i.fa.fa-spinner.fa-pulse.fa-fw - | èªã¿è¾¼ã‚“ã§ã„ã¾ã™ - mk-ellipsis - div.stream(if={ !initializing && images.length > 0 }) - virtual(each={ image in images }) - div.img(style={ 'background-image: url(' + image.url + '?thumbnail&size=256)' }) - p.empty(if={ !initializing && images.length == 0 }) - | 写真ã¯ã‚ã‚Šã¾ã›ã‚“ +<mk-user-photos> + <p class="title"><i class="fa fa-camera"></i>フォト</p> + <p class="initializing" if="{ initializing }"><i class="fa fa-spinner fa-pulse fa-fw"></i>èªã¿è¾¼ã‚“ã§ã„ã¾ã™ + <mk-ellipsis></mk-ellipsis> + </p> + <div class="stream" if="{ !initializing && images.length > 0 }"> + <virtual each="{ image in images }"> + <div class="img" style="{ 'background-image: url(' + image.url + '?thumbnail&size=256)' }"></div> + </virtual> + </div> + <p class="empty" if="{ !initializing && images.length == 0 }">写真ã¯ã‚ã‚Šã¾ã›ã‚“</p> + <style type="stylus"> + :scope + display block + background #fff -style. - display block - background #fff + > .title + z-index 1 + 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 - z-index 1 - 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 - > i - margin-right 4px + > .stream + display -webkit-flex + display -moz-flex + display -ms-flex + display flex + justify-content center + flex-wrap wrap + padding 8px - > .stream - display -webkit-flex - display -moz-flex - display -ms-flex - display flex - justify-content center - flex-wrap wrap - padding 8px + > .img + flex 1 1 33% + width 33% + height 80px + background-position center center + background-size cover + background-clip content-box + border solid 2px transparent - > .img - flex 1 1 33% - width 33% - height 80px - background-position center center - background-size cover - background-clip content-box - border solid 2px transparent + > .initializing + > .empty + margin 0 + padding 16px + text-align center + color #aaa - > .initializing - > .empty - margin 0 - padding 16px - text-align center - color #aaa + > i + margin-right 4px - > i - margin-right 4px + </style> + <script> + @mixin \api + @mixin \is-promise -script. - @mixin \api - @mixin \is-promise + @images = [] + @initializing = true - @images = [] - @initializing = true + @user = null + @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user - @user = null - @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user - - @on \mount ~> - @user-promise.then (user) ~> - @user = user - @update! - - @api \users/posts do - user_id: @user.id - with_media: true - limit: 9posts - .then (posts) ~> - @initializing = false - posts.for-each (post) ~> - post.media.for-each (image) ~> - if @images.length < 9 - @images.push image + @on \mount ~> + @user-promise.then (user) ~> + @user = user @update! + + @api \users/posts do + user_id: @user.id + with_media: true + limit: 9posts + .then (posts) ~> + @initializing = false + posts.for-each (post) ~> + post.media.for-each (image) ~> + if @images.length < 9 + @images.push image + @update! + </script> +</mk-user-photos> diff --git a/src/web/app/desktop/tags/user-posts-graph.tag b/src/web/app/desktop/tags/user-posts-graph.tag index 75f4ac4a67a1ce0a9c21d3cda37a8a0436540675..61070c3818e42541b6c3caa966892b21e2391fb9 100644 --- a/src/web/app/desktop/tags/user-posts-graph.tag +++ b/src/web/app/desktop/tags/user-posts-graph.tag @@ -1,68 +1,71 @@ -mk-user-posts-graph - canvas@canv(width='750', height='250') +<mk-user-posts-graph> + <canvas ref="canv" width="750" height="250"></canvas> + <style type="stylus"> + :scope + display block + width 750px + height 250px -style. - display block - width 750px - height 250px + </style> + <script> + @mixin \api + @mixin \is-promise -script. - @mixin \api - @mixin \is-promise + @user = null + @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user - @user = null - @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user + @on \mount ~> + user <~ @user-promise.then + @user = user + @update! - @on \mount ~> - user <~ @user-promise.then - @user = user - @update! - - @api \aggregation/users/post do - user_id: @user.id - limit: 30days - .then (data) ~> - data = data.reverse! - new Chart @refs.canv, do - type: \line - data: - labels: data.map (x, i) ~> if i % 3 == 2 then x.date.day + 'æ—¥' else '' - datasets: [ - { - label: \投稿 - data: data.map (x) ~> x.posts - line-tension: 0 - point-radius: 0 - background-color: \#555 - border-color: \transparent - }, - { - label: \Repost - data: data.map (x) ~> x.reposts - line-tension: 0 - point-radius: 0 - background-color: \#a2d61e - border-color: \transparent - }, - { - label: \返信 - data: data.map (x) ~> x.replies - line-tension: 0 - point-radius: 0 - background-color: \#F7796C - border-color: \transparent - } - ] - options: - responsive: false - scales: - x-axes: [ + @api \aggregation/users/post do + user_id: @user.id + limit: 30days + .then (data) ~> + data = data.reverse! + new Chart @refs.canv, do + type: \line + data: + labels: data.map (x, i) ~> if i % 3 == 2 then x.date.day + 'æ—¥' else '' + datasets: [ { - stacked: true - } - ] - y-axes: [ + label: \投稿 + data: data.map (x) ~> x.posts + line-tension: 0 + point-radius: 0 + background-color: \#555 + border-color: \transparent + }, + { + label: \Repost + data: data.map (x) ~> x.reposts + line-tension: 0 + point-radius: 0 + background-color: \#a2d61e + border-color: \transparent + }, { - stacked: true + label: \返信 + data: data.map (x) ~> x.replies + line-tension: 0 + point-radius: 0 + background-color: \#F7796C + border-color: \transparent } ] + options: + responsive: false + scales: + x-axes: [ + { + stacked: true + } + ] + y-axes: [ + { + stacked: true + } + ] + </script> +</mk-user-posts-graph> diff --git a/src/web/app/desktop/tags/user-preview.tag b/src/web/app/desktop/tags/user-preview.tag index f299e6236ec387af5a2f3bfc70bca79e81bc21ae..ed1d8687818369da9bb359eaa96f12b4779e7356 100644 --- a/src/web/app/desktop/tags/user-preview.tag +++ b/src/web/app/desktop/tags/user-preview.tag @@ -1,143 +1,148 @@ -mk-user-preview - virtual(if={ user != null }) - div.banner(style={ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=512)' : '' }) - a.avatar(href={ CONFIG.url + '/' + user.username }, target='_blank'): img(src={ user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.title - p.name { user.name } - p.username @{ user.username } - div.bio { user.bio } - div.status - div - p 投稿 - a { user.posts_count } - div - p フォãƒãƒ¼ - a { user.following_count } - div - p フォãƒãƒ¯ãƒ¼ - a { user.followers_count } - mk-follow-button(if={ SIGNIN && user.id != I.id }, user={ user-promise }) - -style. - display block - position absolute - z-index 2048 - width 250px - background #fff - background-clip content-box - border solid 1px rgba(0, 0, 0, 0.1) - border-radius 4px - overflow hidden - - // https://github.com/riot/riot/issues/2081 - > virtual - display block - position relative - - > .banner - height 84px - background-color #f5f5f5 - background-size cover - background-position center - - > .avatar +<mk-user-preview> + <virtual if="{ user != null }"> + <div class="banner" style="{ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=512)' : '' }"></div><a class="avatar" href="{ CONFIG.url + '/' + user.username }" target="_blank"><img src="{ user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/></a> + <div class="title"> + <p class="name">{ user.name }</p> + <p class="username">@{ user.username }</p> + </div> + <div class="bio">{ user.bio }</div> + <div class="status"> + <div> + <p>投稿</p><a>{ user.posts_count }</a> + </div> + <div> + <p>フォãƒãƒ¼</p><a>{ user.following_count }</a> + </div> + <div> + <p>フォãƒãƒ¯ãƒ¼</p><a>{ user.followers_count }</a> + </div> + </div> + <mk-follow-button if="{ SIGNIN && user.id != I.id }" user="{ userPromise }"></mk-follow-button> + </virtual> + <style type="stylus"> + :scope display block position absolute - top 62px - left 13px - - > img - display block - width 58px - height 58px - margin 0 - border solid 3px #fff - border-radius 8px - - > .title - display block - padding 8px 0 8px 85px - - > .name - display block - margin 0 - font-weight bold - line-height 16px - color #656565 - - > .username + z-index 2048 + width 250px + background #fff + background-clip content-box + border solid 1px rgba(0, 0, 0, 0.1) + border-radius 4px + overflow hidden + + // https://github.com/riot/riot/issues/2081 + > virtual display block - margin 0 - line-height 16px - font-size 0.8em - color #999 - - > .bio - padding 0 16px - font-size 0.7em - color #555 - - > .status - padding 8px 16px - - > div - display inline-block - width 33% - - > p - margin 0 + position relative + + > .banner + height 84px + background-color #f5f5f5 + background-size cover + background-position center + + > .avatar + display block + position absolute + top 62px + left 13px + + > img + display block + width 58px + height 58px + margin 0 + border solid 3px #fff + border-radius 8px + + > .title + display block + padding 8px 0 8px 85px + + > .name + display block + margin 0 + font-weight bold + line-height 16px + color #656565 + + > .username + display block + margin 0 + line-height 16px + font-size 0.8em + color #999 + + > .bio + padding 0 16px font-size 0.7em - color #aaa - - > a - font-size 1em - color $theme-color - - > mk-follow-button - position absolute - top 92px - right 8px - -script. - @mixin \i - @mixin \api - - @u = @opts.user - @user = null - @user-promise = - if typeof @u == \string - new Promise (resolve, reject) ~> - @api \users/show do - user_id: if @u.0 == \@ then undefined else @u - username: if @u.0 == \@ then @u.substr 1 else undefined - .then (user) ~> - resolve user - else - Promise.resolve @u - - @on \mount ~> - @user-promise.then (user) ~> - @user = user - @update! - - Velocity @root, { - opacity: 0 - 'margin-top': \-8px - } 0ms - Velocity @root, { - opacity: 1 - 'margin-top': 0 - } { - duration: 200ms - easing: \ease-out - } - - @close = ~> - Velocity @root, { - opacity: 0 - 'margin-top': \-8px - } { - duration: 200ms - easing: \ease-out - complete: ~> @unmount! - } + color #555 + + > .status + padding 8px 16px + + > div + display inline-block + width 33% + + > p + margin 0 + font-size 0.7em + color #aaa + + > a + font-size 1em + color $theme-color + + > mk-follow-button + position absolute + top 92px + right 8px + + </style> + <script> + @mixin \i + @mixin \api + + @u = @opts.user + @user = null + @user-promise = + if typeof @u == \string + new Promise (resolve, reject) ~> + @api \users/show do + user_id: if @u.0 == \@ then undefined else @u + username: if @u.0 == \@ then @u.substr 1 else undefined + .then (user) ~> + resolve user + else + Promise.resolve @u + + @on \mount ~> + @user-promise.then (user) ~> + @user = user + @update! + + Velocity @root, { + opacity: 0 + 'margin-top': \-8px + } 0ms + Velocity @root, { + opacity: 1 + 'margin-top': 0 + } { + duration: 200ms + easing: \ease-out + } + + @close = ~> + Velocity @root, { + opacity: 0 + 'margin-top': \-8px + } { + duration: 200ms + easing: \ease-out + complete: ~> @unmount! + } + </script> +</mk-user-preview> diff --git a/src/web/app/desktop/tags/user-profile.tag b/src/web/app/desktop/tags/user-profile.tag index adb685845c09381ded7fff102b50a7c2d6998c5d..1079282ed372dd024e869afd5e100193c36e636f 100644 --- a/src/web/app/desktop/tags/user-profile.tag +++ b/src/web/app/desktop/tags/user-profile.tag @@ -1,86 +1,83 @@ -mk-user-profile - div.friend-form(if={ SIGNIN && I.id != user.id }) - mk-big-follow-button(user={ user }) - p.followed(if={ user.is_followed }) フォãƒãƒ¼ã•ã‚Œã¦ã„ã¾ã™ - div.bio(if={ user.bio != '' }) { user.bio } - div.birthday(if={ user.birthday }): p - i.fa.fa-birthday-cake - | { user.birthday.replace('-', 'å¹´').replace('-', '月') + 'æ—¥' } - div.friends - p.following - i.fa.fa-angle-right - a(onclick={ show-following }) { user.following_count } - | 人を - b フォãƒãƒ¼ - p.followers - i.fa.fa-angle-right - a(onclick={ show-followers }) { user.followers_count } - | 人㮠- b フォãƒãƒ¯ãƒ¼ - -style. - display block - background #fff - - > *:first-child - border-top none !important - - > .friend-form - padding 16px - border-top solid 1px #eee - - > mk-big-follow-button - width 100% - - > .followed - margin 12px 0 0 0 - padding 0 - text-align center - line-height 24px - font-size 0.8em - color #71afc7 - background #eefaff - border-radius 4px - - > .bio - padding 16px - color #555 - border-top solid 1px #eee - - > .birthday - padding 16px - color #555 - border-top solid 1px #eee - - > p - margin 0 - - > i - margin-right 8px - - > .friends - padding 16px - color #555 - border-top solid 1px #eee - - > p - margin 8px 0 - - > i - margin-left 8px - margin-right 8px - -script. - @mixin \i - - @user = @opts.user - - @show-following = ~> - window = document.body.append-child document.create-element \mk-user-following-window - riot.mount window, do - user: @user - - @show-followers = ~> - window = document.body.append-child document.create-element \mk-user-followers-window - riot.mount window, do - user: @user +<mk-user-profile> + <div class="friend-form" if="{ SIGNIN && I.id != user.id }"> + <mk-big-follow-button user="{ user }"></mk-big-follow-button> + <p class="followed" if="{ user.is_followed }">フォãƒãƒ¼ã•ã‚Œã¦ã„ã¾ã™</p> + </div> + <div class="bio" if="{ user.bio != '' }">{ user.bio }</div> + <div class="birthday" if="{ user.birthday }"> + <p><i class="fa fa-birthday-cake"></i>{ user.birthday.replace('-', 'å¹´').replace('-', '月') + 'æ—¥' }</p> + </div> + <div class="friends"> + <p class="following"><i class="fa fa-angle-right"></i><a onclick="{ showFollowing }">{ user.following_count }</a>人を<b>フォãƒãƒ¼</b></p> + <p class="followers"><i class="fa fa-angle-right"></i><a onclick="{ showFollowers }">{ user.followers_count }</a>人ã®<b>フォãƒãƒ¯ãƒ¼</b></p> + </div> + <style type="stylus"> + :scope + display block + background #fff + + > *:first-child + border-top none !important + + > .friend-form + padding 16px + border-top solid 1px #eee + + > mk-big-follow-button + width 100% + + > .followed + margin 12px 0 0 0 + padding 0 + text-align center + line-height 24px + font-size 0.8em + color #71afc7 + background #eefaff + border-radius 4px + + > .bio + padding 16px + color #555 + border-top solid 1px #eee + + > .birthday + padding 16px + color #555 + border-top solid 1px #eee + + > p + margin 0 + + > i + margin-right 8px + + > .friends + padding 16px + color #555 + border-top solid 1px #eee + + > p + margin 8px 0 + + > i + margin-left 8px + margin-right 8px + + </style> + <script> + @mixin \i + + @user = @opts.user + + @show-following = ~> + window = document.body.append-child document.create-element \mk-user-following-window + riot.mount window, do + user: @user + + @show-followers = ~> + window = document.body.append-child document.create-element \mk-user-followers-window + riot.mount window, do + user: @user + </script> +</mk-user-profile> diff --git a/src/web/app/desktop/tags/user-timeline.tag b/src/web/app/desktop/tags/user-timeline.tag index ced90e2e84566c312571b34a9a0806d63b4ee032..89eb53933a52d5d30bdbde63e0d156070b802121 100644 --- a/src/web/app/desktop/tags/user-timeline.tag +++ b/src/web/app/desktop/tags/user-timeline.tag @@ -1,142 +1,138 @@ -mk-user-timeline - header - span(data-is-active={ mode == 'default' }, onclick={ set-mode.bind(this, 'default') }) 投稿 - span(data-is-active={ mode == 'with-replies' }, onclick={ set-mode.bind(this, 'with-replies') }) 投稿ã¨è¿”ä¿¡ - div.loading(if={ is-loading }) - mk-ellipsis-icon - p.empty(if={ is-empty }) - i.fa.fa-comments-o - | ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã¾ã 何も投稿ã—ã¦ã„ãªã„よã†ã§ã™ã€‚ - 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 +<mk-user-timeline> + <header><span data-is-active="{ mode == 'default' }" onclick="{ setMode.bind(this, 'default') }">投稿</span><span data-is-active="{ mode == 'with-replies' }" onclick="{ setMode.bind(this, 'with-replies') }">投稿ã¨è¿”ä¿¡</span></header> + <div class="loading" if="{ isLoading }"> + <mk-ellipsis-icon></mk-ellipsis-icon> + </div> + <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> + <style type="stylus"> + :scope display block - margin-bottom 16px - font-size 3em - color #ccc - -script. - @mixin \api - @mixin \is-promise - @mixin \get-post-summary - - @user = null - @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user - @is-loading = true - @is-empty = false - @more-loading = false - @unread-count = 0 - @mode = \default - - @on \mount ~> - document.add-event-listener \visibilitychange @window-on-visibilitychange, false - document.add-event-listener \keydown @on-document-keydown - window.add-event-listener \scroll @on-scroll - - @user-promise.then (user) ~> - @user = user - @update! - - @fetch ~> - @trigger \loaded - - @on \unmount ~> - document.remove-event-listener \visibilitychange @window-on-visibilitychange - document.remove-event-listener \keydown @on-document-keydown - window.remove-event-listener \scroll @on-scroll - - @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 \users/posts do - user_id: @user.id - with_replies: @mode == \with-replies - .then (posts) ~> - @is-loading = false - @is-empty = posts.length == 0 + 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 + margin-bottom 16px + font-size 3em + color #ccc + + </style> + <script> + @mixin \api + @mixin \is-promise + @mixin \get-post-summary + + @user = null + @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user + @is-loading = true + @is-empty = false + @more-loading = false + @unread-count = 0 + @mode = \default + + @on \mount ~> + document.add-event-listener \visibilitychange @window-on-visibilitychange, false + document.add-event-listener \keydown @on-document-keydown + window.add-event-listener \scroll @on-scroll + + @user-promise.then (user) ~> + @user = user + @update! + + @fetch ~> + @trigger \loaded + + @on \unmount ~> + document.remove-event-listener \visibilitychange @window-on-visibilitychange + document.remove-event-listener \keydown @on-document-keydown + window.remove-event-listener \scroll @on-scroll + + @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 \users/posts do + user_id: @user.id + with_replies: @mode == \with-replies + .then (posts) ~> + @is-loading = false + @is-empty = posts.length == 0 + @update! + @refs.timeline.set-posts posts + 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! - @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 \users/posts do - user_id: @user.id - with_replies: @mode == \with-replies - max_id: @refs.timeline.tail!.id - .then (posts) ~> - @more-loading = false + @api \users/posts do + user_id: @user.id + with_replies: @mode == \with-replies + max_id: @refs.timeline.tail!.id + .then (posts) ~> + @more-loading = false + @update! + @refs.timeline.prepend-posts posts + .catch (err) ~> + console.error err + + @on-stream-post = (post) ~> + @is-empty = 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 - - if document.hidden - @unread-count++ - document.title = '(' + @unread-count + ') ' + @get-post-summary post - - @window-on-visibilitychange = ~> - if !document.hidden - @unread-count = 0 - document.title = 'Misskey' - - @on-scroll = ~> - current = window.scroll-y + window.inner-height - if current > document.body.offset-height - 16 # éŠã³ - @more! - - @set-mode = (mode) ~> - @update do - mode: mode - @fetch! + @refs.timeline.add-post post + + if document.hidden + @unread-count++ + document.title = '(' + @unread-count + ') ' + @get-post-summary post + + @window-on-visibilitychange = ~> + if !document.hidden + @unread-count = 0 + document.title = 'Misskey' + + @on-scroll = ~> + current = window.scroll-y + window.inner-height + if current > document.body.offset-height - 16 # éŠã³ + @more! + + @set-mode = (mode) ~> + @update do + mode: mode + @fetch! + </script> +</mk-user-timeline> diff --git a/src/web/app/desktop/tags/user.tag b/src/web/app/desktop/tags/user.tag index 4d022e68c43472833465ac2d757eec823ae738b8..777d9caee79a08a3d6bbcd6c3f424a5f03c3c215 100644 --- a/src/web/app/desktop/tags/user.tag +++ b/src/web/app/desktop/tags/user.tag @@ -1,45 +1,51 @@ -mk-user - div.user(if={ !fetching }) - header - mk-user-header(user={ user }) - div.body - mk-user-home(if={ page == 'home' }, user={ user }) - mk-user-graphs(if={ page == 'graphs' }, user={ user }) +<mk-user> + <div class="user" if="{ !fetching }"> + <header> + <mk-user-header user="{ user }"></mk-user-header> + </header> + <div class="body"> + <mk-user-home if="{ page == 'home' }" user="{ user }"></mk-user-home> + <mk-user-graphs if="{ page == 'graphs' }" user="{ user }"></mk-user-graphs> + </div> + </div> + <style type="stylus"> + :scope + display block + background #fff -style. - display block - background #fff + > .user + > header + max-width 560px + 270px + margin 0 auto + padding 0 16px - > .user - > header - max-width 560px + 270px - margin 0 auto - padding 0 16px + > mk-user-header + border solid 1px rgba(0, 0, 0, 0.075) + border-top none + border-radius 0 0 6px 6px + overflow hidden - > mk-user-header - border solid 1px rgba(0, 0, 0, 0.075) - border-top none - border-radius 0 0 6px 6px - overflow hidden + > .body + max-width 560px + 270px + margin 0 auto + padding 0 16px - > .body - max-width 560px + 270px - margin 0 auto - padding 0 16px + </style> + <script> + @mixin \api -script. - @mixin \api + @username = @opts.user + @page = if @opts.page? then @opts.page else \home + @fetching = true + @user = null - @username = @opts.user - @page = if @opts.page? then @opts.page else \home - @fetching = true - @user = null - - @on \mount ~> - @api \users/show do - username: @username - .then (user) ~> - @fetching = false - @user = user - @update! - @trigger \loaded + @on \mount ~> + @api \users/show do + username: @username + .then (user) ~> + @fetching = false + @user = user + @update! + @trigger \loaded + </script> +</mk-user> diff --git a/src/web/app/desktop/tags/users-list.tag b/src/web/app/desktop/tags/users-list.tag index 9ae96eed9f4085ab4954794fc37f249657be675e..e2b0ef1332b480c30125e4967ba6df4c36d8b2bf 100644 --- a/src/web/app/desktop/tags/users-list.tag +++ b/src/web/app/desktop/tags/users-list.tag @@ -1,139 +1,134 @@ -mk-users-list - nav: div - span(data-is-active={ mode == 'all' }, onclick={ set-mode.bind(this, 'all') }) - | ã™ã¹ã¦ - span { opts.count } - // ↓ https://github.com/riot/riot/issues/2080 - span(if={ SIGNIN && opts.you-know-count != '' }, data-is-active={ mode == 'iknow' }, onclick={ set-mode.bind(this, 'iknow') }) - | 知りåˆã„ - span { opts.you-know-count } - - div.users(if={ !fetching && users.length != 0 }) - div(each={ users }): mk-list-user(user={ this }) - - button.more(if={ !fetching && next != null }, onclick={ more }, disabled={ more-fetching }) - span(if={ !more-fetching }) ã‚‚ã£ã¨ - span(if={ more-fetching }) - | èªã¿è¾¼ã¿ä¸ - mk-ellipsis - - p.no(if={ !fetching && users.length == 0 }) - | { opts.no-users } - p.fetching(if={ fetching }) - i.fa.fa-spinner.fa-pulse.fa-fw - | èªã¿è¾¼ã‚“ã§ã„ã¾ã™ - mk-ellipsis - -style. - display block - height 100% - background #fff - - > nav - z-index 1 - box-shadow 0 1px 0 rgba(#000, 0.1) - - > div - display flex - justify-content center - margin 0 auto - max-width 600px - - > span - display block - flex 1 1 +<mk-users-list> + <nav> + <div><span data-is-active="{ mode == 'all' }" onclick="{ setMode.bind(this, 'all') }">ã™ã¹ã¦<span>{ opts.count }</span></span> + <!-- ↓ https://github.com/riot/riot/issues/2080--><span if="{ SIGNIN && opts.youKnowCount != '' }" data-is-active="{ mode == 'iknow' }" onclick="{ setMode.bind(this, 'iknow') }">知りåˆã„<span>{ opts.youKnowCount }</span></span> + </div> + </nav> + <div class="users" if="{ !fetching && users.length != 0 }"> + <div each="{ users }"> + <mk-list-user user="{ this }"></mk-list-user> + </div> + </div> + <button class="more" if="{ !fetching && next != null }" onclick="{ more }" disabled="{ moreFetching }"><span if="{ !moreFetching }">ã‚‚ã£ã¨</span><span if="{ moreFetching }">èªã¿è¾¼ã¿ä¸ + <mk-ellipsis></mk-ellipsis></span></button> + <p class="no" if="{ !fetching && users.length == 0 }">{ opts.noUsers }</p> + <p class="fetching" if="{ fetching }"><i class="fa fa-spinner fa-pulse fa-fw"></i>èªã¿è¾¼ã‚“ã§ã„ã¾ã™ + <mk-ellipsis></mk-ellipsis> + </p> + <style type="stylus"> + :scope + display block + height 100% + background #fff + + > nav + z-index 1 + box-shadow 0 1px 0 rgba(#000, 0.1) + + > div + display flex + justify-content center + margin 0 auto + max-width 600px + + > span + display block + flex 1 1 + text-align center + line-height 52px + font-size 14px + color #657786 + border-bottom solid 2px transparent + cursor pointer + + * + pointer-events none + + &[data-is-active] + font-weight bold + color $theme-color + border-color $theme-color + cursor default + + > span + display inline-block + margin-left 4px + padding 2px 5px + font-size 12px + line-height 1 + color #888 + background #eee + border-radius 20px + + > .users + height calc(100% - 54px) + overflow auto + + > * + border-bottom solid 1px rgba(0, 0, 0, 0.05) + + > * + max-width 600px + margin 0 auto + + > .no + margin 0 + padding 16px text-align center - line-height 52px - font-size 14px - color #657786 - border-bottom solid 2px transparent - cursor pointer - - * - pointer-events none - - &[data-is-active] - font-weight bold - color $theme-color - border-color $theme-color - cursor default - - > span - display inline-block - margin-left 4px - padding 2px 5px - font-size 12px - line-height 1 - color #888 - background #eee - border-radius 20px - - > .users - height calc(100% - 54px) - overflow auto - - > * - border-bottom solid 1px rgba(0, 0, 0, 0.05) - - > * - max-width 600px - margin 0 auto - - > .no - margin 0 - padding 16px - text-align center - color #aaa - - > .fetching - margin 0 - padding 16px - text-align center - color #aaa - - > i - margin-right 4px - -script. - @mixin \i - - @limit = 30users - @mode = \all - - @fetching = true - @more-fetching = false - - @on \mount ~> - @fetch ~> - @trigger \loaded - - @fetch = (cb) ~> + color #aaa + + > .fetching + margin 0 + padding 16px + text-align center + color #aaa + + > i + margin-right 4px + + </style> + <script> + @mixin \i + + @limit = 30users + @mode = \all + @fetching = true - @update! - obj <~ @opts.fetch do - @mode == \iknow - @limit - null - @users = obj.users - @next = obj.next - @fetching = false - @update! - if cb? then cb! - - @more = ~> - @more-fetching = true - @update! - obj <~ @opts.fetch do - @mode == \iknow - @limit - @cursor - @users = @users.concat obj.users - @next = obj.next @more-fetching = false - @update! - - @set-mode = (mode) ~> - @update do - mode: mode - @fetch! + @on \mount ~> + @fetch ~> + @trigger \loaded + + @fetch = (cb) ~> + @fetching = true + @update! + obj <~ @opts.fetch do + @mode == \iknow + @limit + null + @users = obj.users + @next = obj.next + @fetching = false + @update! + if cb? then cb! + + @more = ~> + @more-fetching = true + @update! + obj <~ @opts.fetch do + @mode == \iknow + @limit + @cursor + @users = @users.concat obj.users + @next = obj.next + @more-fetching = false + @update! + + @set-mode = (mode) ~> + @update do + mode: mode + + @fetch! + </script> +</mk-users-list> diff --git a/src/web/app/desktop/tags/window.tag b/src/web/app/desktop/tags/window.tag index 9732a6c55235792ff8e6c6bc87a17780d06f0e3a..750df64df028c83fe954864e032eda04d3557f81 100644 --- a/src/web/app/desktop/tags/window.tag +++ b/src/web/app/desktop/tags/window.tag @@ -1,515 +1,519 @@ -mk-window(data-flexible={ is-flexible }, data-colored={ opts.colored }, ondragover={ ondragover }) - div.bg@bg(show={ is-modal }, onclick={ bg-click }) - div.main@main(tabindex='-1', data-is-modal={ is-modal }, onmousedown={ on-body-mousedown }, onkeydown={ on-keydown }) - div.body - header@header(onmousedown={ on-header-mousedown }) - h1(data-yield='header') - | <yield from="header"/> - button.close(if={ can-close }, onmousedown={ repel-move }, onclick={ close }, title='é–‰ã˜ã‚‹'): i.fa.fa-times - div.content(data-yield='content') - | <yield from="content"/> - div.handle.top(if={ can-resize }, onmousedown={ on-top-handle-mousedown }) - div.handle.right(if={ can-resize }, onmousedown={ on-right-handle-mousedown }) - div.handle.bottom(if={ can-resize }, onmousedown={ on-bottom-handle-mousedown }) - div.handle.left(if={ can-resize }, onmousedown={ on-left-handle-mousedown }) - div.handle.top-left(if={ can-resize }, onmousedown={ on-top-left-handle-mousedown }) - div.handle.top-right(if={ can-resize }, onmousedown={ on-top-right-handle-mousedown }) - div.handle.bottom-right(if={ can-resize }, onmousedown={ on-bottom-right-handle-mousedown }) - div.handle.bottom-left(if={ can-resize }, onmousedown={ on-bottom-left-handle-mousedown }) - -style. - display block - - > .bg - display block - position fixed - z-index 2048 - top 0 - left 0 - width 100% - height 100% - background rgba(0, 0, 0, 0.7) - opacity 0 - pointer-events none - - > .main - display block - position fixed - z-index 2048 - top 15% - left 0 - margin 0 - opacity 0 - pointer-events none - - &:focus - &:not([data-is-modal]) - > .body - box-shadow 0 0 0px 1px rgba($theme-color, 0.5), 0 2px 6px 0 rgba(0, 0, 0, 0.2) - - > .handle - $size = 8px - - position absolute - - &.top - top -($size) - left 0 - width 100% - height $size - cursor ns-resize - - &.right +<mk-window data-flexible="{ isFlexible }" data-colored="{ opts.colored }" ondragover="{ ondragover }"> + <div class="bg" ref="bg" show="{ isModal }" onclick="{ bgClick }"></div> + <div class="main" ref="main" tabindex="-1" data-is-modal="{ isModal }" onmousedown="{ onBodyMousedown }" onkeydown="{ onKeydown }"> + <div class="body"> + <header ref="header" onmousedown="{ onHeaderMousedown }"> + <h1 data-yield="header"><yield from="header"/></h1> + <button class="close" if="{ canClose }" onmousedown="{ repelMove }" onclick="{ close }" title="é–‰ã˜ã‚‹"><i class="fa fa-times"></i></button> + </header> + <div class="content" data-yield="content"><yield from="content"/></div> + </div> + <div class="handle top" if="{ canResize }" onmousedown="{ onTopHandleMousedown }"></div> + <div class="handle right" if="{ canResize }" onmousedown="{ onRightHandleMousedown }"></div> + <div class="handle bottom" if="{ canResize }" onmousedown="{ onBottomHandleMousedown }"></div> + <div class="handle left" if="{ canResize }" onmousedown="{ onLeftHandleMousedown }"></div> + <div class="handle top-left" if="{ canResize }" onmousedown="{ onTopLeftHandleMousedown }"></div> + <div class="handle top-right" if="{ canResize }" onmousedown="{ onTopRightHandleMousedown }"></div> + <div class="handle bottom-right" if="{ canResize }" onmousedown="{ onBottomRightHandleMousedown }"></div> + <div class="handle bottom-left" if="{ canResize }" onmousedown="{ onBottomLeftHandleMousedown }"></div> + </div> + <style type="stylus"> + :scope + display block + + > .bg + display block + position fixed + z-index 2048 top 0 - right -($size) - width $size - height 100% - cursor ew-resize - - &.bottom - bottom -($size) left 0 width 100% - height $size - cursor ns-resize - - &.left - top 0 - left -($size) - width $size - height 100% - cursor ew-resize - - &.top-left - top -($size) - left -($size) - width $size * 2 - height $size * 2 - cursor nwse-resize - - &.top-right - top -($size) - right -($size) - width $size * 2 - height $size * 2 - cursor nesw-resize - - &.bottom-right - bottom -($size) - right -($size) - width $size * 2 - height $size * 2 - cursor nwse-resize - - &.bottom-left - bottom -($size) - left -($size) - width $size * 2 - height $size * 2 - cursor nesw-resize - - > .body - height 100% - overflow hidden - background #fff - border-radius 6px - box-shadow 0 2px 6px 0 rgba(0, 0, 0, 0.2) - - > header - z-index 128 - overflow hidden - cursor move - background #fff - border-radius 6px 6px 0 0 - box-shadow 0 1px 0 rgba(#000, 0.1) - - &, * - user-select none - - > h1 - pointer-events none - display block - margin 0 - height 40px - text-align center - font-size 1em - line-height 40px - font-weight normal - color #666 - - > .close - cursor pointer - display block - position absolute - top 0 - right 0 - z-index 1 - margin 0 - padding 0 - font-size 1.2em - color rgba(#000, 0.4) - border none - outline none - background transparent - - &:hover - color rgba(#000, 0.6) - - &:active - color darken(#000, 30%) - - > i - padding 0 - width 40px - line-height 40px - - > .content height 100% + background rgba(0, 0, 0, 0.7) + opacity 0 + pointer-events none + + > .main + display block + position fixed + z-index 2048 + top 15% + left 0 + margin 0 + opacity 0 + pointer-events none - &:not([flexible]) - > .main > .body > .content - height calc(100% - 40px) - - &[data-colored] - - > .main > .body - - > header - box-shadow 0 1px 0 rgba($theme-color, 0.1) - - > h1 - color #d0b4ac - - > .close - color rgba($theme-color, 0.4) - - &:hover - color rgba($theme-color, 0.6) - - &:active - color darken($theme-color, 30%) + &:focus + &:not([data-is-modal]) + > .body + box-shadow 0 0 0px 1px rgba($theme-color, 0.5), 0 2px 6px 0 rgba(0, 0, 0, 0.2) -script. - @min-height = 40px - @min-width = 200px + > .handle + $size = 8px - @is-modal = if @opts.is-modal? then @opts.is-modal else false - @can-close = if @opts.can-close? then @opts.can-close else true - @is-flexible = !@opts.height? - @can-resize = not @is-flexible + position absolute - @on \mount ~> - @refs.main.style.width = @opts.width || \530px - @refs.main.style.height = @opts.height || \auto + &.top + top -($size) + left 0 + width 100% + height $size + cursor ns-resize + + &.right + top 0 + right -($size) + width $size + height 100% + cursor ew-resize + + &.bottom + bottom -($size) + left 0 + width 100% + height $size + cursor ns-resize + + &.left + top 0 + left -($size) + width $size + height 100% + cursor ew-resize + + &.top-left + top -($size) + left -($size) + width $size * 2 + height $size * 2 + cursor nwse-resize + + &.top-right + top -($size) + right -($size) + width $size * 2 + height $size * 2 + cursor nesw-resize + + &.bottom-right + bottom -($size) + right -($size) + width $size * 2 + height $size * 2 + cursor nwse-resize + + &.bottom-left + bottom -($size) + left -($size) + width $size * 2 + height $size * 2 + cursor nesw-resize - @refs.main.style.top = \15% - @refs.main.style.left = (window.inner-width / 2) - (@refs.main.offset-width / 2) + \px + > .body + height 100% + overflow hidden + background #fff + border-radius 6px + box-shadow 0 2px 6px 0 rgba(0, 0, 0, 0.2) + + > header + z-index 128 + overflow hidden + cursor move + background #fff + border-radius 6px 6px 0 0 + box-shadow 0 1px 0 rgba(#000, 0.1) + + &, * + user-select none + + > h1 + pointer-events none + display block + margin 0 + height 40px + text-align center + font-size 1em + line-height 40px + font-weight normal + color #666 + + > .close + cursor pointer + display block + position absolute + top 0 + right 0 + z-index 1 + margin 0 + padding 0 + font-size 1.2em + color rgba(#000, 0.4) + border none + outline none + background transparent + + &:hover + color rgba(#000, 0.6) + + &:active + color darken(#000, 30%) + + > i + padding 0 + width 40px + line-height 40px + + > .content + height 100% + + &:not([flexible]) + > .main > .body > .content + height calc(100% - 40px) + + &[data-colored] + + > .main > .body + + > header + box-shadow 0 1px 0 rgba($theme-color, 0.1) + + > h1 + color #d0b4ac + + > .close + color rgba($theme-color, 0.4) + + &:hover + color rgba($theme-color, 0.6) + + &:active + color darken($theme-color, 30%) + + </style> + <script> + @min-height = 40px + @min-width = 200px + + @is-modal = if @opts.is-modal? then @opts.is-modal else false + @can-close = if @opts.can-close? then @opts.can-close else true + @is-flexible = !@opts.height? + @can-resize = not @is-flexible + + @on \mount ~> + @refs.main.style.width = @opts.width || \530px + @refs.main.style.height = @opts.height || \auto + + @refs.main.style.top = \15% + @refs.main.style.left = (window.inner-width / 2) - (@refs.main.offset-width / 2) + \px + + @refs.header.add-event-listener \contextmenu (e) ~> + e.prevent-default! - @refs.header.add-event-listener \contextmenu (e) ~> - e.prevent-default! + window.add-event-listener \resize @on-browser-resize - window.add-event-listener \resize @on-browser-resize + @open! - @open! + @on \unmount ~> + window.remove-event-listener \resize @on-browser-resize - @on \unmount ~> - window.remove-event-listener \resize @on-browser-resize + @on-browser-resize = ~> + position = @refs.main.get-bounding-client-rect! + browser-width = window.inner-width + browser-height = window.inner-height + window-width = @refs.main.offset-width + window-height = @refs.main.offset-height - @on-browser-resize = ~> - position = @refs.main.get-bounding-client-rect! - browser-width = window.inner-width - browser-height = window.inner-height - window-width = @refs.main.offset-width - window-height = @refs.main.offset-height + if position.left < 0 + @refs.main.style.left = 0 - if position.left < 0 - @refs.main.style.left = 0 + if position.top < 0 + @refs.main.style.top = 0 - if position.top < 0 - @refs.main.style.top = 0 + if position.left + window-width > browser-width + @refs.main.style.left = browser-width - window-width + \px - if position.left + window-width > browser-width - @refs.main.style.left = browser-width - window-width + \px + if position.top + window-height > browser-height + @refs.main.style.top = browser-height - window-height + \px - if position.top + window-height > browser-height - @refs.main.style.top = browser-height - window-height + \px + @open = ~> + @trigger \opening - @open = ~> - @trigger \opening + @top! - @top! + if @is-modal + @refs.bg.style.pointer-events = \auto + Velocity @refs.bg, \finish true + Velocity @refs.bg, { + opacity: 1 + } { + queue: false + duration: 100ms + easing: \linear + } - if @is-modal - @refs.bg.style.pointer-events = \auto - Velocity @refs.bg, \finish true - Velocity @refs.bg, { + @refs.main.style.pointer-events = \auto + Velocity @refs.main, \finish true + Velocity @refs.main, {scale: 1.1} 0ms + Velocity @refs.main, { opacity: 1 + scale: 1 } { queue: false - duration: 100ms - easing: \linear + duration: 200ms + easing: \ease-out } - @refs.main.style.pointer-events = \auto - Velocity @refs.main, \finish true - Velocity @refs.main, {scale: 1.1} 0ms - Velocity @refs.main, { - opacity: 1 - scale: 1 - } { - queue: false - duration: 200ms - easing: \ease-out - } - - #@refs.main.focus! - - set-timeout ~> - @trigger \opened - , 300ms - - @close = ~> - @trigger \closing - - if @is-modal - @refs.bg.style.pointer-events = \none - Velocity @refs.bg, \finish true - Velocity @refs.bg, { + #@refs.main.focus! + + set-timeout ~> + @trigger \opened + , 300ms + + @close = ~> + @trigger \closing + + if @is-modal + @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: \linear + easing: [ 0.5, -0.5, 1, 0.5 ] } - @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 ] - } - - set-timeout ~> - @trigger \closed - , 300ms - - # 最å‰é¢ã¸ç§»å‹•ã—ã¾ã™ - @top = ~> - z = 0 - - ws = document.query-selector-all \mk-window - ws.for-each (w) !~> - if w == @root then return - m = w.query-selector ':scope > .main' - mz = Number(document.default-view.get-computed-style m, null .z-index) - if mz > z then z := mz - - if z > 0 - @refs.main.style.z-index = z + 1 - if @is-modal then @refs.bg.style.z-index = z + 1 - - @repel-move = (e) ~> - e.stop-propagation! - return true - - @bg-click = ~> - if @can-close - @close! - - @on-body-mousedown = (e) ~> - @top! - true - - # ヘッダー掴ã¿æ™‚ - @on-header-mousedown = (e) ~> - e.prevent-default! - - if not contains @refs.main, document.active-element - @refs.main.focus! - - position = @refs.main.get-bounding-client-rect! - - click-x = e.client-x - click-y = e.client-y - move-base-x = click-x - position.left - move-base-y = click-y - position.top - browser-width = window.inner-width - browser-height = window.inner-height - window-width = @refs.main.offset-width - window-height = @refs.main.offset-height - - # å‹•ã‹ã—ãŸæ™‚ - drag-listen (me) ~> - move-left = me.client-x - move-base-x - move-top = me.client-y - move-base-y - - # 上ã¯ã¿å‡ºã— - if move-top < 0 - move-top = 0 - - # å·¦ã¯ã¿å‡ºã— - if move-left < 0 - move-left = 0 - - # 下ã¯ã¿å‡ºã— - if move-top + window-height > browser-height - move-top = browser-height - window-height - - # å³ã¯ã¿å‡ºã— - if move-left + window-width > browser-width - move-left = browser-width - window-width - - @refs.main.style.left = move-left + \px - @refs.main.style.top = move-top + \px - - # 上ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ - @on-top-handle-mousedown = (e) ~> - e.prevent-default! - - base = e.client-y - height = parse-int((get-computed-style @refs.main, '').height, 10) - top = parse-int((get-computed-style @refs.main, '').top, 10) - - # å‹•ã‹ã—ãŸæ™‚ - drag-listen (me) ~> - move = me.client-y - base - if top + move > 0 - if height + -move > @min-height - @apply-transform-height height + -move - @apply-transform-top top + move - else # 最å°ã®é«˜ã•ã‚ˆã‚Šå°ã•ããªã‚ã†ã¨ã—ãŸæ™‚ - @apply-transform-height @min-height - @apply-transform-top top + (height - @min-height) - else # 上ã®ã¯ã¿å‡ºã—時 - @apply-transform-height top + height - @apply-transform-top 0 - - # å³ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ - @on-right-handle-mousedown = (e) ~> - e.prevent-default! - - base = e.client-x - width = parse-int((get-computed-style @refs.main, '').width, 10) - left = parse-int((get-computed-style @refs.main, '').left, 10) - browser-width = window.inner-width - - # å‹•ã‹ã—ãŸæ™‚ - drag-listen (me) ~> - move = me.client-x - base - if left + width + move < browser-width - if width + move > @min-width - @apply-transform-width width + move - else # 最å°ã®å¹…よりå°ã•ããªã‚ã†ã¨ã—ãŸæ™‚ - @apply-transform-width @min-width - else # å³ã®ã¯ã¿å‡ºã—時 - @apply-transform-width browser-width - left - - # 下ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ - @on-bottom-handle-mousedown = (e) ~> - e.prevent-default! - - base = e.client-y - height = parse-int((get-computed-style @refs.main, '').height, 10) - top = parse-int((get-computed-style @refs.main, '').top, 10) - browser-height = window.inner-height - - # å‹•ã‹ã—ãŸæ™‚ - drag-listen (me) ~> - move = me.client-y - base - if top + height + move < browser-height - if height + move > @min-height - @apply-transform-height height + move - else # 最å°ã®é«˜ã•ã‚ˆã‚Šå°ã•ããªã‚ã†ã¨ã—ãŸæ™‚ - @apply-transform-height @min-height - else # 下ã®ã¯ã¿å‡ºã—時 - @apply-transform-height browser-height - top - - # å·¦ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ - @on-left-handle-mousedown = (e) ~> - e.prevent-default! - - base = e.client-x - width = parse-int((get-computed-style @refs.main, '').width, 10) - left = parse-int((get-computed-style @refs.main, '').left, 10) - - # å‹•ã‹ã—ãŸæ™‚ - drag-listen (me) ~> - move = me.client-x - base - if left + move > 0 - if width + -move > @min-width - @apply-transform-width width + -move - @apply-transform-left left + move - else # 最å°ã®å¹…よりå°ã•ããªã‚ã†ã¨ã—ãŸæ™‚ - @apply-transform-width @min-width - @apply-transform-left left + (width - @min-width) - else # å·¦ã®ã¯ã¿å‡ºã—時 - @apply-transform-width left + width - @apply-transform-left 0 - - # 左上ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ - @on-top-left-handle-mousedown = (e) ~> - @on-top-handle-mousedown e - @on-left-handle-mousedown e - - # å³ä¸Šãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ - @on-top-right-handle-mousedown = (e) ~> - @on-top-handle-mousedown e - @on-right-handle-mousedown e - - # å³ä¸‹ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ - @on-bottom-right-handle-mousedown = (e) ~> - @on-bottom-handle-mousedown e - @on-right-handle-mousedown e - - # 左下ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ - @on-bottom-left-handle-mousedown = (e) ~> - @on-bottom-handle-mousedown e - @on-left-handle-mousedown e - - # 高ã•ã‚’é©ç”¨ - @apply-transform-height = (height) ~> - @refs.main.style.height = height + \px - - # å¹…ã‚’é©ç”¨ - @apply-transform-width = (width) ~> - @refs.main.style.width = width + \px - - # Y座標をé©ç”¨ - @apply-transform-top = (top) ~> - @refs.main.style.top = top + \px - - # X座標をé©ç”¨ - @apply-transform-left = (left) ~> - @refs.main.style.left = left + \px - - function drag-listen fn - window.add-event-listener \mousemove fn - window.add-event-listener \mouseleave drag-clear.bind null fn - window.add-event-listener \mouseup drag-clear.bind null fn - - function drag-clear fn - window.remove-event-listener \mousemove fn - window.remove-event-listener \mouseleave drag-clear - window.remove-event-listener \mouseup drag-clear - - @ondragover = (e) ~> - e.data-transfer.drop-effect = \none - - @on-keydown = (e) ~> - if e.which == 27 # Esc + set-timeout ~> + @trigger \closed + , 300ms + + # 最å‰é¢ã¸ç§»å‹•ã—ã¾ã™ + @top = ~> + z = 0 + + ws = document.query-selector-all \mk-window + ws.for-each (w) !~> + if w == @root then return + m = w.query-selector ':scope > .main' + mz = Number(document.default-view.get-computed-style m, null .z-index) + if mz > z then z := mz + + if z > 0 + @refs.main.style.z-index = z + 1 + if @is-modal then @refs.bg.style.z-index = z + 1 + + @repel-move = (e) ~> + e.stop-propagation! + return true + + @bg-click = ~> if @can-close - e.prevent-default! - e.stop-propagation! @close! - function contains(parent, child) - node = child.parent-node - while node? - if node == parent - return true - node = node.parent-node - return false + @on-body-mousedown = (e) ~> + @top! + true + + # ヘッダー掴ã¿æ™‚ + @on-header-mousedown = (e) ~> + e.prevent-default! + + if not contains @refs.main, document.active-element + @refs.main.focus! + + position = @refs.main.get-bounding-client-rect! + + click-x = e.client-x + click-y = e.client-y + move-base-x = click-x - position.left + move-base-y = click-y - position.top + browser-width = window.inner-width + browser-height = window.inner-height + window-width = @refs.main.offset-width + window-height = @refs.main.offset-height + + # å‹•ã‹ã—ãŸæ™‚ + drag-listen (me) ~> + move-left = me.client-x - move-base-x + move-top = me.client-y - move-base-y + + # 上ã¯ã¿å‡ºã— + if move-top < 0 + move-top = 0 + + # å·¦ã¯ã¿å‡ºã— + if move-left < 0 + move-left = 0 + + # 下ã¯ã¿å‡ºã— + if move-top + window-height > browser-height + move-top = browser-height - window-height + + # å³ã¯ã¿å‡ºã— + if move-left + window-width > browser-width + move-left = browser-width - window-width + + @refs.main.style.left = move-left + \px + @refs.main.style.top = move-top + \px + + # 上ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ + @on-top-handle-mousedown = (e) ~> + e.prevent-default! + + base = e.client-y + height = parse-int((get-computed-style @refs.main, '').height, 10) + top = parse-int((get-computed-style @refs.main, '').top, 10) + + # å‹•ã‹ã—ãŸæ™‚ + drag-listen (me) ~> + move = me.client-y - base + if top + move > 0 + if height + -move > @min-height + @apply-transform-height height + -move + @apply-transform-top top + move + else # 最å°ã®é«˜ã•ã‚ˆã‚Šå°ã•ããªã‚ã†ã¨ã—ãŸæ™‚ + @apply-transform-height @min-height + @apply-transform-top top + (height - @min-height) + else # 上ã®ã¯ã¿å‡ºã—時 + @apply-transform-height top + height + @apply-transform-top 0 + + # å³ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ + @on-right-handle-mousedown = (e) ~> + e.prevent-default! + + base = e.client-x + width = parse-int((get-computed-style @refs.main, '').width, 10) + left = parse-int((get-computed-style @refs.main, '').left, 10) + browser-width = window.inner-width + + # å‹•ã‹ã—ãŸæ™‚ + drag-listen (me) ~> + move = me.client-x - base + if left + width + move < browser-width + if width + move > @min-width + @apply-transform-width width + move + else # 最å°ã®å¹…よりå°ã•ããªã‚ã†ã¨ã—ãŸæ™‚ + @apply-transform-width @min-width + else # å³ã®ã¯ã¿å‡ºã—時 + @apply-transform-width browser-width - left + + # 下ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ + @on-bottom-handle-mousedown = (e) ~> + e.prevent-default! + + base = e.client-y + height = parse-int((get-computed-style @refs.main, '').height, 10) + top = parse-int((get-computed-style @refs.main, '').top, 10) + browser-height = window.inner-height + + # å‹•ã‹ã—ãŸæ™‚ + drag-listen (me) ~> + move = me.client-y - base + if top + height + move < browser-height + if height + move > @min-height + @apply-transform-height height + move + else # 最å°ã®é«˜ã•ã‚ˆã‚Šå°ã•ããªã‚ã†ã¨ã—ãŸæ™‚ + @apply-transform-height @min-height + else # 下ã®ã¯ã¿å‡ºã—時 + @apply-transform-height browser-height - top + + # å·¦ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ + @on-left-handle-mousedown = (e) ~> + e.prevent-default! + + base = e.client-x + width = parse-int((get-computed-style @refs.main, '').width, 10) + left = parse-int((get-computed-style @refs.main, '').left, 10) + + # å‹•ã‹ã—ãŸæ™‚ + drag-listen (me) ~> + move = me.client-x - base + if left + move > 0 + if width + -move > @min-width + @apply-transform-width width + -move + @apply-transform-left left + move + else # 最å°ã®å¹…よりå°ã•ããªã‚ã†ã¨ã—ãŸæ™‚ + @apply-transform-width @min-width + @apply-transform-left left + (width - @min-width) + else # å·¦ã®ã¯ã¿å‡ºã—時 + @apply-transform-width left + width + @apply-transform-left 0 + + # 左上ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ + @on-top-left-handle-mousedown = (e) ~> + @on-top-handle-mousedown e + @on-left-handle-mousedown e + + # å³ä¸Šãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ + @on-top-right-handle-mousedown = (e) ~> + @on-top-handle-mousedown e + @on-right-handle-mousedown e + + # å³ä¸‹ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ + @on-bottom-right-handle-mousedown = (e) ~> + @on-bottom-handle-mousedown e + @on-right-handle-mousedown e + + # 左下ãƒãƒ³ãƒ‰ãƒ«æŽ´ã¿æ™‚ + @on-bottom-left-handle-mousedown = (e) ~> + @on-bottom-handle-mousedown e + @on-left-handle-mousedown e + + # 高ã•ã‚’é©ç”¨ + @apply-transform-height = (height) ~> + @refs.main.style.height = height + \px + + # å¹…ã‚’é©ç”¨ + @apply-transform-width = (width) ~> + @refs.main.style.width = width + \px + + # Y座標をé©ç”¨ + @apply-transform-top = (top) ~> + @refs.main.style.top = top + \px + + # X座標をé©ç”¨ + @apply-transform-left = (left) ~> + @refs.main.style.left = left + \px + + function drag-listen fn + window.add-event-listener \mousemove fn + window.add-event-listener \mouseleave drag-clear.bind null fn + window.add-event-listener \mouseup drag-clear.bind null fn + + function drag-clear fn + window.remove-event-listener \mousemove fn + window.remove-event-listener \mouseleave drag-clear + window.remove-event-listener \mouseup drag-clear + + @ondragover = (e) ~> + e.data-transfer.drop-effect = \none + + @on-keydown = (e) ~> + if e.which == 27 # Esc + if @can-close + e.prevent-default! + e.stop-propagation! + @close! + + function contains(parent, child) + node = child.parent-node + while node? + if node == parent + return true + node = node.parent-node + return false + </script> +</mk-window> diff --git a/src/web/app/dev/tags/new-app-form.tag b/src/web/app/dev/tags/new-app-form.tag index 443bf2bfff34642e23161c407e52c56d496df75a..c74a43d151aa7344cd9395984357f476879089ac 100644 --- a/src/web/app/dev/tags/new-app-form.tag +++ b/src/web/app/dev/tags/new-app-form.tag @@ -1,260 +1,243 @@ -mk-new-app-form - form(onsubmit={ onsubmit }, autocomplete='off') - section.name: label - p.caption - | アプリケーションå - input@name( - type='text' - placeholder='ex) Misskey for iOS' - autocomplete='off' - required) - - section.nid: label - p.caption - | Named ID - input@nid( - type='text' - pattern='^[a-zA-Z0-9\-]{3,30}$' - placeholder='ex) misskey-for-ios' - autocomplete='off' - required - onkeyup={ on-change-nid }) - - p.info(if={ nid-state == 'wait' }, style='color:#999') - i.fa.fa-fw.fa-spinner.fa-pulse - | 確èªã—ã¦ã„ã¾ã™... - p.info(if={ nid-state == 'ok' }, style='color:#3CB7B5') - i.fa.fa-fw.fa-check - | 利用ã§ãã¾ã™ - p.info(if={ nid-state == 'unavailable' }, style='color:#FF1161') - i.fa.fa-fw.fa-exclamation-triangle - | æ—¢ã«åˆ©ç”¨ã•ã‚Œã¦ã„ã¾ã™ - p.info(if={ nid-state == 'error' }, style='color:#FF1161') - i.fa.fa-fw.fa-exclamation-triangle - | 通信エラー - p.info(if={ nid-state == 'invalid-format' }, style='color:#FF1161') - i.fa.fa-fw.fa-exclamation-triangle - | a~zã€A~Zã€0~9ã€-(ãƒã‚¤ãƒ•ãƒ³)ãŒä½¿ãˆã¾ã™ - p.info(if={ nid-state == 'min-range' }, style='color:#FF1161') - i.fa.fa-fw.fa-exclamation-triangle - | 3æ–‡å—以上ã§ãŠé¡˜ã„ã—ã¾ã™ï¼ - p.info(if={ nid-state == 'max-range' }, style='color:#FF1161') - i.fa.fa-fw.fa-exclamation-triangle - | 30æ–‡å—以内ã§ãŠé¡˜ã„ã—ã¾ã™ - - section.description: label - p.caption - | アプリã®æ¦‚è¦ - textarea@description( - placeholder='ex) Misskey iOSクライアント。' - autocomplete='off' - required) - - section.callback: label - p.caption - | コールãƒãƒƒã‚¯URL (オプション) - input@cb( - type='url' - placeholder='ex) https://your.app.example.com/callback.php' - autocomplete='off') - - section.permission - p.caption - | æ¨©é™ - div@permission - label - input(type='checkbox', value='account-read') - p アカウントã®æƒ…å ±ã‚’è¦‹ã‚‹ã€‚ - label - input(type='checkbox', value='account-write') - p アカウントã®æƒ…å ±ã‚’æ“作ã™ã‚‹ã€‚ - label - input(type='checkbox', value='post-write') - p 投稿ã™ã‚‹ã€‚ - label - input(type='checkbox', value='like-write') - p ã„ã„ãã—ãŸã‚Šã„ã„ã解除ã™ã‚‹ã€‚ - label - input(type='checkbox', value='following-write') - p フォãƒãƒ¼ã—ãŸã‚Šãƒ•ã‚©ãƒãƒ¼è§£é™¤ã™ã‚‹ã€‚ - label - input(type='checkbox', value='drive-read') - p ドライブを見る。 - label - input(type='checkbox', value='drive-write') - p ドライブをæ“作ã™ã‚‹ã€‚ - label - input(type='checkbox', value='notification-read') - p 通知を見る。 - label - input(type='checkbox', value='notification-write') - p 通知をæ“作ã™ã‚‹ã€‚ - p - i.fa.fa-exclamation-triangle - | アプリ作æˆå¾Œã‚‚変更ã§ãã¾ã™ãŒã€æ–°ãŸãªæ¨©é™ã‚’付与ã™ã‚‹å ´åˆã€ãã®æ™‚点ã§é–¢é€£ä»˜ã‘られã¦ã„るユーザーã‚ーã¯ã™ã¹ã¦ç„¡åŠ¹ã«ãªã‚Šã¾ã™ã€‚ - - button(onclick={ onsubmit }) - | ã‚¢ãƒ—ãƒªä½œæˆ - -style. - display block - overflow hidden - - > form - - section +<mk-new-app-form> + <form onsubmit="{ onsubmit }" autocomplete="off"> + <section class="name"> + <label> + <p class="caption">アプリケーションå</p> + <input ref="name" type="text" placeholder="ex) Misskey for iOS" autocomplete="off" required="required"/> + </label> + </section> + <section class="nid"> + <label> + <p class="caption">Named ID</p> + <input ref="nid" type="text" pattern="^[a-zA-Z0-9-]{3,30}$" placeholder="ex) misskey-for-ios" autocomplete="off" required="required" onkeyup="{ onChangeNid }"/> + <p class="info" if="{ nidState == 'wait' }" style="color:#999"><i class="fa fa-fw fa-spinner fa-pulse"></i>確èªã—ã¦ã„ã¾ã™...</p> + <p class="info" if="{ nidState == 'ok' }" style="color:#3CB7B5"><i class="fa fa-fw fa-check"></i>利用ã§ãã¾ã™</p> + <p class="info" if="{ nidState == 'unavailable' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>æ—¢ã«åˆ©ç”¨ã•ã‚Œã¦ã„ã¾ã™</p> + <p class="info" if="{ nidState == 'error' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>通信エラー</p> + <p class="info" if="{ nidState == 'invalid-format' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>a~zã€A~Zã€0~9ã€-(ãƒã‚¤ãƒ•ãƒ³)ãŒä½¿ãˆã¾ã™</p> + <p class="info" if="{ nidState == 'min-range' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>3æ–‡å—以上ã§ãŠé¡˜ã„ã—ã¾ã™ï¼</p> + <p class="info" if="{ nidState == 'max-range' }" style="color:#FF1161"><i class="fa fa-fw fa-exclamation-triangle"></i>30æ–‡å—以内ã§ãŠé¡˜ã„ã—ã¾ã™</p> + </label> + </section> + <section class="description"> + <label> + <p class="caption">アプリã®æ¦‚è¦</p> + <textarea ref="description" placeholder="ex) Misskey iOSクライアント。" autocomplete="off" required="required"></textarea> + </label> + </section> + <section class="callback"> + <label> + <p class="caption">コールãƒãƒƒã‚¯URL (オプション)</p> + <input ref="cb" type="url" placeholder="ex) https://your.app.example.com/callback.php" autocomplete="off"/> + </label> + </section> + <section class="permission"> + <p class="caption">権é™</p> + <div ref="permission"> + <label> + <input type="checkbox" value="account-read"/> + <p>アカウントã®æƒ…å ±ã‚’è¦‹ã‚‹ã€‚</p> + </label> + <label> + <input type="checkbox" value="account-write"/> + <p>アカウントã®æƒ…å ±ã‚’æ“作ã™ã‚‹ã€‚</p> + </label> + <label> + <input type="checkbox" value="post-write"/> + <p>投稿ã™ã‚‹ã€‚</p> + </label> + <label> + <input type="checkbox" value="like-write"/> + <p>ã„ã„ãã—ãŸã‚Šã„ã„ã解除ã™ã‚‹ã€‚</p> + </label> + <label> + <input type="checkbox" value="following-write"/> + <p>フォãƒãƒ¼ã—ãŸã‚Šãƒ•ã‚©ãƒãƒ¼è§£é™¤ã™ã‚‹ã€‚</p> + </label> + <label> + <input type="checkbox" value="drive-read"/> + <p>ドライブを見る。</p> + </label> + <label> + <input type="checkbox" value="drive-write"/> + <p>ドライブをæ“作ã™ã‚‹ã€‚</p> + </label> + <label> + <input type="checkbox" value="notification-read"/> + <p>通知を見る。</p> + </label> + <label> + <input type="checkbox" value="notification-write"/> + <p>通知をæ“作ã™ã‚‹ã€‚</p> + </label> + </div> + <p><i class="fa fa-exclamation-triangle"></i>アプリ作æˆå¾Œã‚‚変更ã§ãã¾ã™ãŒã€æ–°ãŸãªæ¨©é™ã‚’付与ã™ã‚‹å ´åˆã€ãã®æ™‚点ã§é–¢é€£ä»˜ã‘られã¦ã„るユーザーã‚ーã¯ã™ã¹ã¦ç„¡åŠ¹ã«ãªã‚Šã¾ã™ã€‚</p> + </section> + <button onclick="{ onsubmit }">アプリ作æˆ</button> + </form> + <style type="stylus"> + :scope display block - margin 16px 0 - - .caption - margin 0 0 4px 0 - color #616161 - font-size 0.95em - - > i - margin-right 0.25em - color #96adac - - .info - display block - margin 4px 0 - font-size 0.8em - - > i - margin-right 0.3em - - section.permission - div - padding 8px 0 - max-height 160px - overflow auto - background #fff - border solid 1px #cecece - border-radius 4px - - label - display block - padding 0 12px - line-height 32px - cursor pointer - - &:hover - > p + overflow hidden + + > form + + section + display block + margin 16px 0 + + .caption + margin 0 0 4px 0 + color #616161 + font-size 0.95em + + > i + margin-right 0.25em + color #96adac + + .info + display block + margin 4px 0 + font-size 0.8em + + > i + margin-right 0.3em + + section.permission + div + padding 8px 0 + max-height 160px + overflow auto + background #fff + border solid 1px #cecece + border-radius 4px + + label + display block + padding 0 12px + line-height 32px + cursor pointer + + &:hover + > p + color #999 + + [type='checkbox']:checked + p + color #000 + + [type='checkbox'] + margin-right 4px + + [type='checkbox']:checked + p + color #111 + + > p + display inline + color #aaa + user-select none + + > p:last-child + margin 6px + font-size 0.8em color #999 - [type='checkbox']:checked + p - color #000 + > i + margin-right 4px + + [type=text] + [type=url] + textarea + user-select text + display inline-block + cursor auto + padding 8px 12px + margin 0 + width 100% + font-size 1em + color #333 + background #fff + outline none + border solid 1px #cecece + border-radius 4px + + &:hover + border-color #bbb + + &:focus + border-color $theme-color + + &:disabled + opacity 0.5 + + > button + margin 20px 0 32px 0 + width 100% + font-size 1em + color #111 + border-radius 3px - [type='checkbox'] - margin-right 4px + </style> + <script> + @mixin \api - [type='checkbox']:checked + p - color #111 + @nid-state = null - > p - display inline - color #aaa - user-select none - - > p:last-child - margin 6px - font-size 0.8em - color #999 - - > i - margin-right 4px - - [type=text] - [type=url] - textarea - user-select text - display inline-block - cursor auto - padding 8px 12px - margin 0 - width 100% - font-size 1em - color #333 - background #fff - outline none - border solid 1px #cecece - border-radius 4px - - &:hover - border-color #bbb - - &:focus - border-color $theme-color - - &:disabled - opacity 0.5 - - > button - margin 20px 0 32px 0 - width 100% - font-size 1em - color #111 - border-radius 3px - -script. - @mixin \api - - @nid-state = null - - @on-change-nid = ~> - nid = @refs.nid.value - - if nid == '' - @nid-state = null - @update! - return - - err = switch - | not nid.match /^[a-zA-Z0-9\-]+$/ => \invalid-format - | nid.length < 3chars => \min-range - | nid.length > 30chars => \max-range - | _ => null - - if err? - @nid-state = err - @update! - else - @nid-state = \wait - @update! - - @api \app/name_id/available do - name_id: nid - .then (result) ~> - if result.available - @nid-state = \ok - else - @nid-state = \unavailable + @on-change-nid = ~> + nid = @refs.nid.value + + if nid == '' + @nid-state = null @update! - .catch (err) ~> - @nid-state = \error + return + + err = switch + | not nid.match /^[a-zA-Z0-9\-]+$/ => \invalid-format + | nid.length < 3chars => \min-range + | nid.length > 30chars => \max-range + | _ => null + + if err? + @nid-state = err + @update! + else + @nid-state = \wait @update! - @onsubmit = ~> - name = @refs.name.value - nid = @refs.nid.value - description = @refs.description.value - cb = @refs.cb.value - permission = [] - - @refs.permission.query-selector-all \input .for-each (el) ~> - if el.checked then permission.push el.value - - locker = document.body.append-child document.create-element \mk-locker - - @api \app/create do - name: name - name_id: nid - description: description - callback_url: cb - permission: permission.join \, - .then ~> - location.href = '/apps' - .catch ~> - alert 'アプリã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚å†åº¦ãŠè©¦ã—ãã ã•ã„。' - - locker.parent-node.remove-child locker + @api \app/name_id/available do + name_id: nid + .then (result) ~> + if result.available + @nid-state = \ok + else + @nid-state = \unavailable + @update! + .catch (err) ~> + @nid-state = \error + @update! + + @onsubmit = ~> + name = @refs.name.value + nid = @refs.nid.value + description = @refs.description.value + cb = @refs.cb.value + permission = [] + + @refs.permission.query-selector-all \input .for-each (el) ~> + if el.checked then permission.push el.value + + locker = document.body.append-child document.create-element \mk-locker + + @api \app/create do + name: name + name_id: nid + description: description + callback_url: cb + permission: permission.join \, + .then ~> + location.href = '/apps' + .catch ~> + alert 'アプリã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚å†åº¦ãŠè©¦ã—ãã ã•ã„。' + + locker.parent-node.remove-child locker + </script> +</mk-new-app-form> diff --git a/src/web/app/dev/tags/pages/app.tag b/src/web/app/dev/tags/pages/app.tag index aa9ba68f3f919788d429a455be377336a763f7e3..4311f115650d90ec1c2cd1dedd1f24cfa10d04e8 100644 --- a/src/web/app/dev/tags/pages/app.tag +++ b/src/web/app/dev/tags/pages/app.tag @@ -1,24 +1,30 @@ -mk-app-page - p(if={ fetching }) èªã¿è¾¼ã¿ä¸ - main(if={ !fetching }) - header - h1 { app.name } - div.body - p App Secret - input(value={ app.secret }, readonly) +<mk-app-page> + <p if="{ fetching }">èªã¿è¾¼ã¿ä¸</p> + <main if="{ !fetching }"> + <header> + <h1>{ app.name }</h1> + </header> + <div class="body"> + <p>App Secret</p> + <input value="{ app.secret }" readonly="readonly"/> + </div> + </main> + <style type="stylus"> + :scope + display block -style. - display block + </style> + <script> + @mixin \api -script. - @mixin \api + @fetching = true - @fetching = true - - @on \mount ~> - @api \app/show do - app_id: @opts.app - .then (app) ~> - @app = app - @fetching = false - @update! + @on \mount ~> + @api \app/show do + app_id: @opts.app + .then (app) ~> + @app = app + @fetching = false + @update! + </script> +</mk-app-page> diff --git a/src/web/app/dev/tags/pages/apps.tag b/src/web/app/dev/tags/pages/apps.tag index f46a9d32828da1e81aa1a0b8a4bd75524df88e99..b7eb441faa676300bbdffe74da80a3f2fc2b3c40 100644 --- a/src/web/app/dev/tags/pages/apps.tag +++ b/src/web/app/dev/tags/pages/apps.tag @@ -1,26 +1,30 @@ -mk-apps-page - h1 ã‚¢ãƒ—ãƒªã‚’ç®¡ç† - a(href='/app/new') ã‚¢ãƒ—ãƒªä½œæˆ - div.apps - p(if={ fetching }) èªã¿è¾¼ã¿ä¸ - virtual(if={ !fetching }) - p(if={ apps.length == 0 }) アプリãªã— - ul(if={ apps.length > 0 }) - li(each={ app in apps }) - a(href={ '/app/' + app.id }) - p.name { app.name } +<mk-apps-page> + <h1>アプリを管ç†</h1><a href="/app/new">アプリ作æˆ</a> + <div class="apps"> + <p if="{ fetching }">èªã¿è¾¼ã¿ä¸</p> + <virtual if="{ !fetching }"> + <p if="{ apps.length == 0 }">アプリãªã—</p> + <ul if="{ apps.length > 0 }"> + <li each="{ app in apps }"><a href="{ '/app/' + app.id }"> + <p class="name">{ app.name }</p></a></li> + </ul> + </virtual> + </div> + <style type="stylus"> + :scope + display block -style. - display block + </style> + <script> + @mixin \api -script. - @mixin \api + @fetching = true - @fetching = true - - @on \mount ~> - @api \my/apps - .then (apps) ~> - @fetching = false - @apps = apps - @update! + @on \mount ~> + @api \my/apps + .then (apps) ~> + @fetching = false + @apps = apps + @update! + </script> +</mk-apps-page> diff --git a/src/web/app/dev/tags/pages/index.tag b/src/web/app/dev/tags/pages/index.tag index 7bc57fbb00938241cd061c445499cac4790d8c4b..6be52e61ba6a306fd85934590c743b32723421d2 100644 --- a/src/web/app/dev/tags/pages/index.tag +++ b/src/web/app/dev/tags/pages/index.tag @@ -1,5 +1,11 @@ -mk-index - a(href='/apps') アプリ +<mk-index><a href="/apps">アプリ</a> + <style type="stylus"> + :scope + display block -style. - display block + + + + + </style> +</mk-index> diff --git a/src/web/app/dev/tags/pages/new-app.tag b/src/web/app/dev/tags/pages/new-app.tag index 8c19e39f4b003980ffb6423292bde7b0bea7f501..f255b84328fe3be9140b5f4c7146e3b570a7a801 100644 --- a/src/web/app/dev/tags/pages/new-app.tag +++ b/src/web/app/dev/tags/pages/new-app.tag @@ -1,33 +1,42 @@ -mk-new-app-page - main - header - h1 æ–°ã—ã„ã‚¢ãƒ—ãƒªã‚’ä½œæˆ - p Misskeyã®APIを利用ã—ãŸã‚¢ãƒ—リケーションを作æˆã§ãã¾ã™ã€‚ - mk-new-app-form +<mk-new-app-page> + <main> + <header> + <h1>æ–°ã—ã„アプリを作æˆ</h1> + <p>Misskeyã®APIを利用ã—ãŸã‚¢ãƒ—リケーションを作æˆã§ãã¾ã™ã€‚</p> + </header> + <mk-new-app-form></mk-new-app-form> + </main> + <style type="stylus"> + :scope + display block + padding 64px 0 -style. - display block - padding 64px 0 + > main + width 100% + max-width 700px + margin 0 auto - > main - width 100% - max-width 700px - margin 0 auto + > header + margin 0 0 16px 0 + padding 0 0 16px 0 + border-bottom solid 1px #282827 - > header - margin 0 0 16px 0 - padding 0 0 16px 0 - border-bottom solid 1px #282827 + > h1 + margin 0 0 12px 0 + padding 0 + line-height 32px + font-size 32px + font-weight normal + color #000 - > h1 - margin 0 0 12px 0 - padding 0 - line-height 32px - font-size 32px - font-weight normal - color #000 + > p + margin 0 + line-height 16px + color #9a9894 - > p - margin 0 - line-height 16px - color #9a9894 + + + + + </style> +</mk-new-app-page> diff --git a/src/web/app/mobile/tags/drive-selector.tag b/src/web/app/mobile/tags/drive-selector.tag index 442299026e2c25103b42551d20d255763ec03e16..f4fd24326fdc162e3f5cfe8246171c326b9169b9 100644 --- a/src/web/app/mobile/tags/drive-selector.tag +++ b/src/web/app/mobile/tags/drive-selector.tag @@ -1,75 +1,78 @@ -mk-drive-selector - div.body - header - h1 - | ファイルをé¸æŠž - span.count(if={ files.length > 0 }) ({ files.length }) - button.close(onclick={ cancel }): i.fa.fa-times - button.ok(onclick={ ok }): i.fa.fa-check - mk-drive@browser(select={ true }, multiple={ opts.multiple }) +<mk-drive-selector> + <div class="body"> + <header> + <h1>ファイルをé¸æŠž<span class="count" if="{ files.length > 0 }">({ files.length })</span></h1> + <button class="close" onclick="{ cancel }"><i class="fa fa-times"></i></button> + <button class="ok" onclick="{ ok }"><i class="fa fa-check"></i></button> + </header> + <mk-drive ref="browser" select="{ true }" multiple="{ opts.multiple }"></mk-drive> + </div> + <style type="stylus"> + :scope + display block -style. - display block - - > .body - position fixed - z-index 2048 - top 0 - left 0 - right 0 - margin 0 auto - width 100% - max-width 500px - height 100% - overflow hidden - background #fff - box-shadow 0 0 16px rgba(#000, 0.3) + > .body + position fixed + z-index 2048 + top 0 + left 0 + right 0 + margin 0 auto + width 100% + max-width 500px + height 100% + overflow hidden + background #fff + box-shadow 0 0 16px rgba(#000, 0.3) - > header - border-bottom solid 1px #eee + > header + border-bottom solid 1px #eee - > h1 - margin 0 - padding 0 - text-align center - line-height 42px - font-size 1em - font-weight normal + > h1 + margin 0 + padding 0 + text-align center + line-height 42px + font-size 1em + font-weight normal - > .count - margin-left 4px - opacity 0.5 + > .count + margin-left 4px + opacity 0.5 - > .close - position absolute - top 0 - left 0 - line-height 42px - width 42px + > .close + position absolute + top 0 + left 0 + line-height 42px + width 42px - > .ok - position absolute - top 0 - right 0 - line-height 42px - width 42px + > .ok + position absolute + top 0 + right 0 + line-height 42px + width 42px - > mk-drive - height calc(100% - 42px) - overflow scroll + > mk-drive + height calc(100% - 42px) + overflow scroll -script. - @files = [] + </style> + <script> + @files = [] - @on \mount ~> - @refs.browser.on \change-selected (files) ~> - @files = files - @update! + @on \mount ~> + @refs.browser.on \change-selected (files) ~> + @files = files + @update! - @cancel = ~> - @trigger \canceled - @unmount! + @cancel = ~> + @trigger \canceled + @unmount! - @ok = ~> - @trigger \selected @files - @unmount! + @ok = ~> + @trigger \selected @files + @unmount! + </script> +</mk-drive-selector> diff --git a/src/web/app/mobile/tags/drive.tag b/src/web/app/mobile/tags/drive.tag index fcc78d1e688faeae5696e3789c8446536dccd2fa..005f16d58fa3c5ba9dfed8a960aa8e8145b2cfe0 100644 --- a/src/web/app/mobile/tags/drive.tag +++ b/src/web/app/mobile/tags/drive.tag @@ -1,338 +1,342 @@ -mk-drive - nav - p(onclick={ go-root }) - i.fa.fa-cloud - | ドライブ - virtual(each={ folder in hierarchy-folders }) - span: i.fa.fa-angle-right - p(onclick={ _move }) { folder.name } - span(if={ folder != null }): i.fa.fa-angle-right - p(if={ folder != null }) { folder.name } - div.browser(if={ file == null }, class={ loading: loading }) - div.folders(if={ folders.length > 0 }) - virtual(each={ folder in folders }) - mk-drive-folder(folder={ folder }) - p(if={ more-folders }) - | ã‚‚ã£ã¨èªã¿è¾¼ã‚€ - div.files(if={ files.length > 0 }) - virtual(each={ file in files }) - mk-drive-file(file={ file }) - p(if={ more-files }) - | ã‚‚ã£ã¨èªã¿è¾¼ã‚€ - div.empty(if={ files.length == 0 && folders.length == 0 && !loading }) - p(if={ !folder == null }) - | ドライブã«ã¯ä½•ã‚‚ã‚ã‚Šã¾ã›ã‚“。 - p(if={ folder != null }) - | ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã¯ç©ºã§ã™ - div.loading(if={ loading }). +<mk-drive> + <nav> + <p onclick="{ goRoot }"><i class="fa fa-cloud"></i>ドライブ</p> + <virtual each="{ folder in hierarchyFolders }"><span><i class="fa fa-angle-right"></i></span> + <p onclick="{ _move }">{ folder.name }</p> + </virtual><span if="{ folder != null }"><i class="fa fa-angle-right"></i></span> + <p if="{ folder != null }">{ folder.name }</p> + </nav> + <div class="browser { loading: loading }" if="{ file == null }"> + <div class="folders" if="{ folders.length > 0 }"> + <virtual each="{ folder in folders }"> + <mk-drive-folder folder="{ folder }"></mk-drive-folder> + </virtual> + <p if="{ moreFolders }">ã‚‚ã£ã¨èªã¿è¾¼ã‚€</p> + </div> + <div class="files" if="{ files.length > 0 }"> + <virtual each="{ file in files }"> + <mk-drive-file file="{ file }"></mk-drive-file> + </virtual> + <p if="{ moreFiles }">ã‚‚ã£ã¨èªã¿è¾¼ã‚€</p> + </div> + <div class="empty" if="{ files.length == 0 && folders.length == 0 && !loading }"> + <p if="{ !folder == null }">ドライブã«ã¯ä½•ã‚‚ã‚ã‚Šã¾ã›ã‚“。</p> + <p if="{ folder != null }">ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã¯ç©ºã§ã™</p> + </div> + <div class="loading" if="{ loading }"> <div class="spinner"> <div class="dot1"></div> <div class="dot2"></div> </div> - mk-drive-file-viewer(if={ file != null }, file={ file }) - -style. - display block - background #fff - - > nav - display block - width 100% - padding 10px 12px - overflow auto - white-space nowrap - font-size 0.9em - color #555 - background #fff - border-bottom solid 1px #dfdfdf - - > p - display inline - margin 0 - padding 0 - - &:last-child - font-weight bold - - > i - margin-right 4px - - > span - margin 0 8px - opacity 0.5 - - > .browser - &.loading - opacity 0.5 - - > .folders - > mk-drive-folder - border-bottom solid 1px #eee - - > .files - > mk-drive-file - border-bottom solid 1px #eee - - > .empty - padding 16px - text-align center - color #999 - pointer-events none - - > p - margin 0 - - > .loading - .spinner - margin 100px auto - width 40px - height 40px - text-align center - - animation sk-rotate 2.0s infinite linear - - .dot1, .dot2 - width 60% - height 60% - display inline-block - position absolute - top 0 - background-color rgba(0, 0, 0, 0.3) - border-radius 100% - - animation sk-bounce 2.0s infinite ease-in-out - - .dot2 - top auto - bottom 0 - animation-delay -1.0s - - @keyframes sk-rotate { 100% { transform: rotate(360deg); }} - - @keyframes sk-bounce { - 0%, 100% { - transform: scale(0.0); - } 50% { - transform: scale(1.0); - } - } - -script. - @mixin \api - @mixin \stream - - @files = [] - @folders = [] - @hierarchy-folders = [] - @selected-files = [] - - # ç¾åœ¨ã®éšŽå±¤(フォルダ) - # * null ã§ãƒ«ãƒ¼ãƒˆã‚’表㙠- @folder = null - - @file = null - - @is-select-mode = @opts.select? and @opts.select - @multiple = if @opts.multiple? then @opts.multiple else false - - @on \mount ~> - @stream.on \drive_file_created @on-stream-drive-file-created - @stream.on \drive_file_updated @on-stream-drive-file-updated - @stream.on \drive_folder_created @on-stream-drive-folder-created - @stream.on \drive_folder_updated @on-stream-drive-folder-updated - - # Riotã®ãƒã‚°ã§nullを渡ã—ã¦ã‚‚""ã«ãªã‚‹ - # https://github.com/riot/riot/issues/2080 - #if @opts.folder? - if @opts.folder? and @opts.folder != '' - @cd @opts.folder - else - @load! - - @on \unmount ~> - @stream.off \drive_file_created @on-stream-drive-file-created - @stream.off \drive_file_updated @on-stream-drive-file-updated - @stream.off \drive_folder_created @on-stream-drive-folder-created - @stream.off \drive_folder_updated @on-stream-drive-folder-updated - - @on-stream-drive-file-created = (file) ~> - @add-file file, true - - @on-stream-drive-file-updated = (file) ~> - current = if @folder? then @folder.id else null - if current != file.folder_id - @remove-file file - else + </div> + </div> + <mk-drive-file-viewer if="{ file != null }" file="{ file }"></mk-drive-file-viewer> + <style type="stylus"> + :scope + display block + background #fff + + > nav + display block + width 100% + padding 10px 12px + overflow auto + white-space nowrap + font-size 0.9em + color #555 + background #fff + border-bottom solid 1px #dfdfdf + + > p + display inline + margin 0 + padding 0 + + &:last-child + font-weight bold + + > i + margin-right 4px + + > span + margin 0 8px + opacity 0.5 + + > .browser + &.loading + opacity 0.5 + + > .folders + > mk-drive-folder + border-bottom solid 1px #eee + + > .files + > mk-drive-file + border-bottom solid 1px #eee + + > .empty + padding 16px + text-align center + color #999 + pointer-events none + + > p + margin 0 + + > .loading + .spinner + margin 100px auto + width 40px + height 40px + text-align center + + animation sk-rotate 2.0s infinite linear + + .dot1, .dot2 + width 60% + height 60% + display inline-block + position absolute + top 0 + background-color rgba(0, 0, 0, 0.3) + border-radius 100% + + animation sk-bounce 2.0s infinite ease-in-out + + .dot2 + top auto + bottom 0 + animation-delay -1.0s + + @keyframes sk-rotate { 100% { transform: rotate(360deg); }} + + @keyframes sk-bounce { + 0%, 100% { + transform: scale(0.0); + } 50% { + transform: scale(1.0); + } + } + + </style> + <script> + @mixin \api + @mixin \stream + + @files = [] + @folders = [] + @hierarchy-folders = [] + @selected-files = [] + + # ç¾åœ¨ã®éšŽå±¤(フォルダ) + # * null ã§ãƒ«ãƒ¼ãƒˆã‚’表㙠+ @folder = null + + @file = null + + @is-select-mode = @opts.select? and @opts.select + @multiple = if @opts.multiple? then @opts.multiple else false + + @on \mount ~> + @stream.on \drive_file_created @on-stream-drive-file-created + @stream.on \drive_file_updated @on-stream-drive-file-updated + @stream.on \drive_folder_created @on-stream-drive-folder-created + @stream.on \drive_folder_updated @on-stream-drive-folder-updated + + # Riotã®ãƒã‚°ã§nullを渡ã—ã¦ã‚‚""ã«ãªã‚‹ + # https://github.com/riot/riot/issues/2080 + #if @opts.folder? + if @opts.folder? and @opts.folder != '' + @cd @opts.folder + else + @load! + + @on \unmount ~> + @stream.off \drive_file_created @on-stream-drive-file-created + @stream.off \drive_file_updated @on-stream-drive-file-updated + @stream.off \drive_folder_created @on-stream-drive-folder-created + @stream.off \drive_folder_updated @on-stream-drive-folder-updated + + @on-stream-drive-file-created = (file) ~> @add-file file, true - @on-stream-drive-folder-created = (folder) ~> - @add-folder folder, true + @on-stream-drive-file-updated = (file) ~> + current = if @folder? then @folder.id else null + if current != file.folder_id + @remove-file file + else + @add-file file, true - @on-stream-drive-folder-updated = (folder) ~> - current = if @folder? then @folder.id else null - if current != folder.parent_id - @remove-folder folder - else + @on-stream-drive-folder-created = (folder) ~> @add-folder folder, true - @_move = (ev) ~> - @move ev.item.folder + @on-stream-drive-folder-updated = (folder) ~> + current = if @folder? then @folder.id else null + if current != folder.parent_id + @remove-folder folder + else + @add-folder folder, true - @move = (target-folder) ~> - @cd target-folder, true + @_move = (ev) ~> + @move ev.item.folder - @cd = (target-folder, is-move) ~> - if target-folder? and typeof target-folder == \object - target-folder = target-folder.id + @move = (target-folder) ~> + @cd target-folder, true - if target-folder == null - @go-root! - return + @cd = (target-folder, is-move) ~> + if target-folder? and typeof target-folder == \object + target-folder = target-folder.id - @loading = true - @update! + if target-folder == null + @go-root! + return - @api \drive/folders/show do - folder_id: target-folder - .then (folder) ~> - @folder = folder - @hierarchy-folders = [] + @loading = true + @update! - x = (f) ~> - @hierarchy-folders.unshift f - if f.parent? - x f.parent + @api \drive/folders/show do + folder_id: target-folder + .then (folder) ~> + @folder = folder + @hierarchy-folders = [] - if folder.parent? - x folder.parent + x = (f) ~> + @hierarchy-folders.unshift f + if f.parent? + x f.parent + + if folder.parent? + x folder.parent + + @update! + if is-move then @trigger \move @folder + @trigger \cd @folder + @load! + .catch (err, text-status) -> + console.error err + + @add-folder = (folder, unshift = false) ~> + current = if @folder? then @folder.id else null + if current != folder.parent_id + return + + if (@folders.some (f) ~> f.id == folder.id) + return + + if unshift + @folders.unshift folder + else + @folders.push folder @update! - if is-move then @trigger \move @folder - @trigger \cd @folder - @load! - .catch (err, text-status) -> - console.error err - - @add-folder = (folder, unshift = false) ~> - current = if @folder? then @folder.id else null - if current != folder.parent_id - return - - if (@folders.some (f) ~> f.id == folder.id) - return - - if unshift - @folders.unshift folder - else - @folders.push folder - - @update! - - @add-file = (file, unshift = false) ~> - current = if @folder? then @folder.id else null - if current != file.folder_id - return - - if (@files.some (f) ~> f.id == file.id) - exist = (@files.map (f) -> f.id).index-of file.id - @files[exist] = file - @update! - return - - if unshift - @files.unshift file - else - @files.push file - - @update! - - @remove-folder = (folder) ~> - if typeof folder == \object - folder = folder.id - @folders = @folders.filter (f) -> f.id != folder - @update! - - @remove-file = (file) ~> - if typeof file == \object - file = file.id - @files = @files.filter (f) -> f.id != file - @update! - - @go-root = ~> - if @folder != null - @folder = null - @hierarchy-folders = [] - @update! - @trigger \move-root - @load! - @load = ~> - @folders = [] - @files = [] - @more-folders = false - @more-files = false - @loading = true - @update! - - @trigger \begin-load - - load-folders = null - load-files = null - - folders-max = 20 - files-max = 20 - - # フォルダ一覧å–å¾— - @api \drive/folders do - folder_id: if @folder? then @folder.id else null - limit: folders-max + 1 - .then (folders) ~> - if folders.length == folders-max + 1 - @more-folders = true - folders.pop! - load-folders := folders - complete! - .catch (err, text-status) ~> - console.error err - - # ファイル一覧å–å¾— - @api \drive/files do - folder_id: if @folder? then @folder.id else null - limit: files-max + 1 - .then (files) ~> - if files.length == files-max + 1 - @more-files = true - files.pop! - load-files := files - complete! - .catch (err, text-status) ~> - console.error err - - flag = false - complete = ~> - if flag - load-folders.for-each (folder) ~> - @add-folder folder - load-files.for-each (file) ~> - @add-file file - @loading = false + @add-file = (file, unshift = false) ~> + current = if @folder? then @folder.id else null + if current != file.folder_id + return + + if (@files.some (f) ~> f.id == file.id) + exist = (@files.map (f) -> f.id).index-of file.id + @files[exist] = file @update! + return - @trigger \loaded + if unshift + @files.unshift file else - flag := true - @trigger \load-mid - - @choose-file = (file) ~> - if @is-select-mode - exist = @selected-files.some (f) ~> f.id == file.id - if exist - @selected-files = (@selected-files.filter (f) ~> f.id != file.id) - else - @selected-files.push file + @files.push file + @update! - @trigger \change-selected @selected-files - else - @file = file + + @remove-folder = (folder) ~> + if typeof folder == \object + folder = folder.id + @folders = @folders.filter (f) -> f.id != folder @update! - @trigger \open-file @file + + @remove-file = (file) ~> + if typeof file == \object + file = file.id + @files = @files.filter (f) -> f.id != file + @update! + + @go-root = ~> + if @folder != null + @folder = null + @hierarchy-folders = [] + @update! + @trigger \move-root + @load! + + @load = ~> + @folders = [] + @files = [] + @more-folders = false + @more-files = false + @loading = true + @update! + + @trigger \begin-load + + load-folders = null + load-files = null + + folders-max = 20 + files-max = 20 + + # フォルダ一覧å–å¾— + @api \drive/folders do + folder_id: if @folder? then @folder.id else null + limit: folders-max + 1 + .then (folders) ~> + if folders.length == folders-max + 1 + @more-folders = true + folders.pop! + load-folders := folders + complete! + .catch (err, text-status) ~> + console.error err + + # ファイル一覧å–å¾— + @api \drive/files do + folder_id: if @folder? then @folder.id else null + limit: files-max + 1 + .then (files) ~> + if files.length == files-max + 1 + @more-files = true + files.pop! + load-files := files + complete! + .catch (err, text-status) ~> + console.error err + + flag = false + complete = ~> + if flag + load-folders.for-each (folder) ~> + @add-folder folder + load-files.for-each (file) ~> + @add-file file + @loading = false + @update! + + @trigger \loaded + else + flag := true + @trigger \load-mid + + @choose-file = (file) ~> + if @is-select-mode + exist = @selected-files.some (f) ~> f.id == file.id + if exist + @selected-files = (@selected-files.filter (f) ~> f.id != file.id) + else + @selected-files.push file + @update! + @trigger \change-selected @selected-files + else + @file = file + @update! + @trigger \open-file @file + </script> +</mk-drive> diff --git a/src/web/app/mobile/tags/drive/file-viewer.tag b/src/web/app/mobile/tags/drive/file-viewer.tag index 8ce89a06f48fd97c8b0b80a8a868962e64011657..ac426278b31afb6ce11e3c559a8e288342ea3bfb 100644 --- a/src/web/app/mobile/tags/drive/file-viewer.tag +++ b/src/web/app/mobile/tags/drive/file-viewer.tag @@ -1,8 +1,9 @@ -mk-drive-file-viewer - p.name { file.name } +<mk-drive-file-viewer> + <p class="name">{ file.name }</p> + <style type="stylus"> + :scope + display block -style. - display block - -script. - @file = @opts.file + </style> + <script>@file = @opts.file</script> +</mk-drive-file-viewer> diff --git a/src/web/app/mobile/tags/drive/file.tag b/src/web/app/mobile/tags/drive/file.tag index ec271441a523336dc8272ddb9788cda71eaf293f..3a2aa87731acdc96264bfdf124d513da4cf3fed0 100644 --- a/src/web/app/mobile/tags/drive/file.tag +++ b/src/web/app/mobile/tags/drive/file.tag @@ -1,130 +1,137 @@ -mk-drive-file(onclick={ onclick }, data-is-selected={ is-selected }) - div.container - div.thumbnail(style={ 'background-image: url(' + file.url + '?thumbnail&size=128)' }) - div.body - p.name { file.name } - // - if file.tags.length > 0 - ul.tags - each tag in file.tags - li.tag(style={background: tag.color, color: contrast(tag.color)})= tag.name - footer - p.type - mk-file-type-icon(file={ file }) - | { file.type } - p.separator - p.data-size { bytes-to-size(file.datasize) } - p.separator - p.created-at - i.fa.fa-clock-o - mk-time(time={ file.created_at }) - -style. - display block - - &, * - user-select none - - * - pointer-events none - - > .container - max-width 500px - margin 0 auto - padding 16px - - &:after - content "" +<mk-drive-file onclick="{ onclick }" data-is-selected="{ isSelected }"> + <div class="container"> + <div class="thumbnail" style="{ 'background-image: url(' + file.url + '?thumbnail&size=128)' }"></div> + <div class="body"> + <p class="name">{ file.name }</p> + <!-- + if file.tags.length > 0 + ul.tags + each tag in file.tags + li.tag(style="{background: tag.color, color: contrast(tag.color)}")= tag.name + --> + <footer> + <p class="type"> + <mk-file-type-icon file="{ file }"></mk-file-type-icon>{ file.type } + </p> + <p class="separator"></p> + <p class="data-size">{ bytesToSize(file.datasize) }</p> + <p class="separator"></p> + <p class="created-at"><i class="fa fa-clock-o"></i> + <mk-time time="{ file.created_at }"></mk-time> + </p> + </footer> + </div> + </div> + <style type="stylus"> + :scope display block - clear both - > .thumbnail - display block - float left - width 64px - height 64px - background-size cover - background-position center center - - > .body - display block - float left - width calc(100% - 74px) - margin-left 10px - - > .name - display block - margin 0 - padding 0 - font-size 0.9em - font-weight bold - color #555 - text-overflow ellipsis - word-wrap break-word - - > .tags - display block - margin 4px 0 0 0 - padding 0 - list-style none - font-size 0.5em - - > .tag - display inline-block - margin 0 5px 0 0 - padding 1px 5px - border-radius 2px - - > footer - display block - margin 4px 0 0 0 - font-size 0.7em - - > .separator - display inline - margin 0 - padding 0 4px - color #CDCDCD - - > .type - display inline - margin 0 - padding 0 - color #9D9D9D - - > mk-file-type-icon - margin-right 4px - - > .data-size - display inline - margin 0 - padding 0 - color #9D9D9D - - > .created-at - display inline - margin 0 - padding 0 - color #BDBDBD - - > i - margin-right 2px - - &[data-is-selected] - background $theme-color - - &, * - color #fff !important - -script. - @mixin \bytes-to-size - - @browser = @parent - @file = @opts.file - @is-selected = @browser.selected-files.some (f) ~> f.id == @file.id - - @browser.on \change-selected (selects) ~> - @is-selected = selects.some (f) ~> f.id == @file.id - - @onclick = ~> - @browser.choose-file @file + &, * + user-select none + + * + pointer-events none + + > .container + max-width 500px + margin 0 auto + padding 16px + + &:after + content "" + display block + clear both + + > .thumbnail + display block + float left + width 64px + height 64px + background-size cover + background-position center center + + > .body + display block + float left + width calc(100% - 74px) + margin-left 10px + + > .name + display block + margin 0 + padding 0 + font-size 0.9em + font-weight bold + color #555 + text-overflow ellipsis + word-wrap break-word + + > .tags + display block + margin 4px 0 0 0 + padding 0 + list-style none + font-size 0.5em + + > .tag + display inline-block + margin 0 5px 0 0 + padding 1px 5px + border-radius 2px + + > footer + display block + margin 4px 0 0 0 + font-size 0.7em + + > .separator + display inline + margin 0 + padding 0 4px + color #CDCDCD + + > .type + display inline + margin 0 + padding 0 + color #9D9D9D + + > mk-file-type-icon + margin-right 4px + + > .data-size + display inline + margin 0 + padding 0 + color #9D9D9D + + > .created-at + display inline + margin 0 + padding 0 + color #BDBDBD + + > i + margin-right 2px + + &[data-is-selected] + background $theme-color + + &, * + color #fff !important + + </style> + <script> + @mixin \bytes-to-size + + @browser = @parent + @file = @opts.file + @is-selected = @browser.selected-files.some (f) ~> f.id == @file.id + + @browser.on \change-selected (selects) ~> + @is-selected = selects.some (f) ~> f.id == @file.id + + @onclick = ~> + @browser.choose-file @file + </script> +</mk-drive-file> diff --git a/src/web/app/mobile/tags/drive/folder.tag b/src/web/app/mobile/tags/drive/folder.tag index ef3a72ea93acf7077b9aa2a006b54145683bad91..5a13686d4feb6669812ede90b344fb25b106c2e8 100644 --- a/src/web/app/mobile/tags/drive/folder.tag +++ b/src/web/app/mobile/tags/drive/folder.tag @@ -1,45 +1,46 @@ -mk-drive-folder(onclick={ onclick }) - div.container - p.name - i.fa.fa-folder - | { folder.name } - i.fa.fa-angle-right - -style. - display block - color #777 - - &, * - user-select none - - * - pointer-events none - - > .container - max-width 500px - margin 0 auto - padding 16px - - > .name +<mk-drive-folder onclick="{ onclick }"> + <div class="container"> + <p class="name"><i class="fa fa-folder"></i>{ folder.name }</p><i class="fa fa-angle-right"></i> + </div> + <style type="stylus"> + :scope display block - margin 0 - padding 0 - - > i - margin-right 6px - - > i - position absolute - top 0 - bottom 0 - right 8px - margin auto 0 auto 0 - width 1em - height 1em - -script. - @browser = @parent - @folder = @opts.folder - - @onclick = ~> - @browser.move @folder + color #777 + + &, * + user-select none + + * + pointer-events none + + > .container + max-width 500px + margin 0 auto + padding 16px + + > .name + display block + margin 0 + padding 0 + + > i + margin-right 6px + + > i + position absolute + top 0 + bottom 0 + right 8px + margin auto 0 auto 0 + width 1em + height 1em + + </style> + <script> + @browser = @parent + @folder = @opts.folder + + @onclick = ~> + @browser.move @folder + </script> +</mk-drive-folder> diff --git a/src/web/app/mobile/tags/follow-button.tag b/src/web/app/mobile/tags/follow-button.tag index 7cedbbee888a9f0d981004844e43e0b3d1a82326..d44fd3b79ba9642783fdb7f720d934b782882b0d 100644 --- a/src/web/app/mobile/tags/follow-button.tag +++ b/src/web/app/mobile/tags/follow-button.tag @@ -1,108 +1,105 @@ -mk-follow-button - button(if={ !init }, class={ wait: wait, follow: !user.is_following, unfollow: user.is_following }, - onclick={ onclick }, - disabled={ wait }) - i.fa.fa-minus(if={ !wait && user.is_following }) - i.fa.fa-plus(if={ !wait && !user.is_following }) - i.fa.fa-spinner.fa-pulse.fa-fw(if={ wait }) - | { user.is_following ? 'フォãƒãƒ¼è§£é™¤' : 'フォãƒãƒ¼' } - div.init(if={ init }): i.fa.fa-spinner.fa-pulse.fa-fw - -style. - display block - - > button - > .init - display block - user-select none - cursor pointer - padding 0 16px - margin 0 - height inherit - font-size 16px - outline none - border solid 1px $theme-color - border-radius 4px - - * - pointer-events none - - &.follow - color $theme-color - background transparent - - &:hover - background rgba($theme-color, 0.1) - - &:active - background rgba($theme-color, 0.2) - - &.unfollow - color $theme-color-foreground - background $theme-color - - &.wait - cursor wait !important - opacity 0.7 - - &.init - cursor wait !important - opacity 0.7 - - > i - margin-right 4px - -script. - @mixin \api - @mixin \is-promise - @mixin \stream - - @user = null - @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user - @init = true - @wait = false - - @on \mount ~> - @user-promise.then (user) ~> - @user = user - @init = false - @update! - @stream.on \follow @on-stream-follow - @stream.on \unfollow @on-stream-unfollow - - @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 +<mk-follow-button> + <button class="{ wait: wait, follow: !user.is_following, unfollow: user.is_following }" if="{ !init }" onclick="{ onclick }" disabled="{ wait }"><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>{ user.is_following ? 'フォãƒãƒ¼è§£é™¤' : 'フォãƒãƒ¼' }</button> + <div class="init" if="{ init }"><i class="fa fa-spinner fa-pulse fa-fw"></i></div> + <style type="stylus"> + :scope + display block + + > button + > .init + display block + user-select none + cursor pointer + padding 0 16px + margin 0 + height inherit + font-size 16px + outline none + border solid 1px $theme-color + border-radius 4px + + * + pointer-events none + + &.follow + color $theme-color + background transparent + + &:hover + background rgba($theme-color, 0.1) + + &:active + background rgba($theme-color, 0.2) + + &.unfollow + color $theme-color-foreground + background $theme-color + + &.wait + cursor wait !important + opacity 0.7 + + &.init + cursor wait !important + opacity 0.7 + + > i + margin-right 4px + + </style> + <script> + @mixin \api + @mixin \is-promise + @mixin \stream + + @user = null + @user-promise = if @is-promise @opts.user then @opts.user else Promise.resolve @opts.user + @init = true + @wait = false + + @on \mount ~> + @user-promise.then (user) ~> + @user = user + @init = false @update! - else - @api \following/create do - user_id: @user.id - .then ~> - @user.is_following = true - .catch (err) -> - console.error err - .then ~> - @wait = false + @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! + 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> diff --git a/src/web/app/mobile/tags/home-timeline.tag b/src/web/app/mobile/tags/home-timeline.tag index 1754bb2b0773fc37d20ec4247344cea609e4372d..6ad7270cef77b4187dedacca49321ed7b3ae65f0 100644 --- a/src/web/app/mobile/tags/home-timeline.tag +++ b/src/web/app/mobile/tags/home-timeline.tag @@ -1,40 +1,43 @@ -mk-home-timeline - mk-timeline@timeline(init={ init }, more={ more }, empty={ '表示ã™ã‚‹æŠ•ç¨¿ãŒã‚ã‚Šã¾ã›ã‚“。誰ã‹ã—らをフォãƒãƒ¼ã™ã‚‹ãªã©ã—ã¾ã—ょã†ã€‚' }) - -style. - display block - -script. - @mixin \api - @mixin \stream - - @init = new Promise (res, rej) ~> - @api \posts/timeline - .then (posts) ~> - res posts - @trigger \loaded - - @on \mount ~> - @stream.on \post @on-stream-post - @stream.on \follow @on-stream-follow - @stream.on \unfollow @on-stream-unfollow - - @on \unmount ~> - @stream.off \post @on-stream-post - @stream.off \follow @on-stream-follow - @stream.off \unfollow @on-stream-unfollow - - @more = ~> - @api \posts/timeline do - max_id: @refs.timeline.tail!.id - - @on-stream-post = (post) ~> - @is-empty = false - @update! - @refs.timeline.add-post post - - @on-stream-follow = ~> - @fetch! - - @on-stream-unfollow = ~> - @fetch! +<mk-home-timeline> + <mk-timeline ref="timeline" init="{ init }" more="{ more }" empty="{ '表示ã™ã‚‹æŠ•ç¨¿ãŒã‚ã‚Šã¾ã›ã‚“。誰ã‹ã—らをフォãƒãƒ¼ã™ã‚‹ãªã©ã—ã¾ã—ょã†ã€‚' }"></mk-timeline> + <style type="stylus"> + :scope + display block + + </style> + <script> + @mixin \api + @mixin \stream + + @init = new Promise (res, rej) ~> + @api \posts/timeline + .then (posts) ~> + res posts + @trigger \loaded + + @on \mount ~> + @stream.on \post @on-stream-post + @stream.on \follow @on-stream-follow + @stream.on \unfollow @on-stream-unfollow + + @on \unmount ~> + @stream.off \post @on-stream-post + @stream.off \follow @on-stream-follow + @stream.off \unfollow @on-stream-unfollow + + @more = ~> + @api \posts/timeline do + max_id: @refs.timeline.tail!.id + + @on-stream-post = (post) ~> + @is-empty = false + @update! + @refs.timeline.add-post post + + @on-stream-follow = ~> + @fetch! + + @on-stream-unfollow = ~> + @fetch! + </script> +</mk-home-timeline> diff --git a/src/web/app/mobile/tags/home.tag b/src/web/app/mobile/tags/home.tag index ebcf8f0bb2fedef38450e8f54ba622a531be72c8..e34d678126392d7c998f54aa42107a7ed8cbe601 100644 --- a/src/web/app/mobile/tags/home.tag +++ b/src/web/app/mobile/tags/home.tag @@ -1,17 +1,20 @@ -mk-home - mk-home-timeline@tl +<mk-home> + <mk-home-timeline ref="tl"></mk-home-timeline> + <style type="stylus"> + :scope + display block -style. - display block + > mk-home-timeline + max-width 600px + margin 0 auto - > mk-home-timeline - max-width 600px - margin 0 auto + @media (min-width 500px) + padding 16px - @media (min-width 500px) - padding 16px - -script. - @on \mount ~> - @refs.tl.on \loaded ~> - @trigger \loaded + </style> + <script> + @on \mount ~> + @refs.tl.on \loaded ~> + @trigger \loaded + </script> +</mk-home> diff --git a/src/web/app/mobile/tags/images-viewer.tag b/src/web/app/mobile/tags/images-viewer.tag index f9d774a1246ac7c18eaf0bebc1f3d29d7037a0ba..12bb8e345d171204e24104e308844d86f099949a 100644 --- a/src/web/app/mobile/tags/images-viewer.tag +++ b/src/web/app/mobile/tags/images-viewer.tag @@ -1,25 +1,27 @@ -mk-images-viewer - div.image@view(onclick={ click }) - img@img(src={ image.url + '?thumbnail&size=512' }, alt={ image.name }, title={ image.name }) - -style. - display block - padding 8px - overflow hidden - box-shadow 0 0 4px rgba(0, 0, 0, 0.2) - border-radius 4px +<mk-images-viewer> + <div class="image" ref="view" onclick="{ click }"><img ref="img" src="{ image.url + '?thumbnail&size=512' }" alt="{ image.name }" title="{ image.name }"/></div> + <style type="stylus"> + :scope + display block + padding 8px + overflow hidden + box-shadow 0 0 4px rgba(0, 0, 0, 0.2) + border-radius 4px - > .image + > .image - > img - display block - max-height 256px - max-width 100% - margin 0 auto + > img + display block + max-height 256px + max-width 100% + margin 0 auto -script. - @images = @opts.images - @image = @images.0 + </style> + <script> + @images = @opts.images + @image = @images.0 - @click = ~> - window.open @image.url + @click = ~> + window.open @image.url + </script> +</mk-images-viewer> diff --git a/src/web/app/mobile/tags/notification-preview.tag b/src/web/app/mobile/tags/notification-preview.tag index ee936df7aba23fe84d650e3014fd23402fed13f4..c6b7414a81ed4a568519b273d170ec045fcbb975 100644 --- a/src/web/app/mobile/tags/notification-preview.tag +++ b/src/web/app/mobile/tags/notification-preview.tag @@ -1,117 +1,109 @@ -mk-notification-preview(class={ notification.type }) - div.main(if={ notification.type == 'like' }) - img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-thumbs-o-up - | { notification.user.name } - p.post-ref { get-post-summary(notification.post) } - - div.main(if={ notification.type == 'repost' }) - img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-retweet - | { notification.post.user.name } - p.post-ref { get-post-summary(notification.post.repost) } - - div.main(if={ notification.type == 'quote' }) - img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-quote-left - | { notification.post.user.name } - p.post-preview { get-post-summary(notification.post) } - - div.main(if={ notification.type == 'follow' }) - img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-user-plus - | { notification.user.name } - - div.main(if={ notification.type == 'reply' }) - img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-reply - | { notification.post.user.name } - p.post-preview { get-post-summary(notification.post) } - - div.main(if={ notification.type == 'mention' }) - img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-at - | { notification.post.user.name } - p.post-preview { get-post-summary(notification.post) } - -style. - display block - margin 0 - padding 8px - color #fff - - > .main - word-wrap break-word - - &:after - content "" - display block - clear both - - img - display block - float left - 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 +<mk-notification-preview class="{ notification.type }"> + <div class="main" if="{ notification.type == 'like' }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/> + <div class="text"> + <p><i class="fa fa-thumbs-o-up"></i>{ notification.user.name }</p> + <p class="post-ref">{ getPostSummary(notification.post) }</p> + </div> + </div> + <div class="main" if="{ notification.type == 'repost' }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/> + <div class="text"> + <p><i class="fa fa-retweet"></i>{ notification.post.user.name }</p> + <p class="post-ref">{ getPostSummary(notification.post.repost) }</p> + </div> + </div> + <div class="main" if="{ notification.type == 'quote' }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/> + <div class="text"> + <p><i class="fa fa-quote-left"></i>{ notification.post.user.name }</p> + <p class="post-preview">{ getPostSummary(notification.post) }</p> + </div> + </div> + <div class="main" if="{ notification.type == 'follow' }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/> + <div class="text"> + <p><i class="fa fa-user-plus"></i>{ notification.user.name }</p> + </div> + </div> + <div class="main" if="{ notification.type == 'reply' }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/> + <div class="text"> + <p><i class="fa fa-reply"></i>{ notification.post.user.name }</p> + <p class="post-preview">{ getPostSummary(notification.post) }</p> + </div> + </div> + <div class="main" if="{ notification.type == 'mention' }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/> + <div class="text"> + <p><i class="fa fa-at"></i>{ notification.post.user.name }</p> + <p class="post-preview">{ getPostSummary(notification.post) }</p> + </div> + </div> + <style type="stylus"> + :scope + display block margin 0 - - i - margin-right 4px - - .post-ref - - &: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 + padding 8px color #fff -script. - @mixin \get-post-summary - @notification = @opts.notification + > .main + word-wrap break-word + + &:after + content "" + display block + clear both + + img + display block + float left + 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-ref + + &: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 #fff + + </style> + <script> + @mixin \get-post-summary + @notification = @opts.notification + </script> +</mk-notification-preview> diff --git a/src/web/app/mobile/tags/notification.tag b/src/web/app/mobile/tags/notification.tag index afcc7441b41a1392cf831d31e3bdd9908b1c5e37..155ebf2930c148cf73d5aadf7380d1182691c382 100644 --- a/src/web/app/mobile/tags/notification.tag +++ b/src/web/app/mobile/tags/notification.tag @@ -1,142 +1,122 @@ -mk-notification(class={ notification.type }) - mk-time(time={ notification.created_at }) - - div.main(if={ notification.type == 'like' }) - a.avatar-anchor(href={ CONFIG.url + '/' + notification.user.username }) - img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-thumbs-o-up - a(href={ CONFIG.url + '/' + notification.user.username }) { 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 }) - img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-retweet - a(href={ CONFIG.url + '/' + notification.post.user.username }) { 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 }) - img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-quote-left - a(href={ CONFIG.url + '/' + notification.post.user.username }) { 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 }) - img.avatar(src={ notification.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-user-plus - a(href={ CONFIG.url + '/' + notification.user.username }) { notification.user.name } - - div.main(if={ notification.type == 'reply' }) - a.avatar-anchor(href={ CONFIG.url + '/' + notification.post.user.username }) - img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-reply - a(href={ CONFIG.url + '/' + notification.post.user.username }) { 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 }) - img.avatar(src={ notification.post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.text - p - i.fa.fa-at - a(href={ CONFIG.url + '/' + notification.post.user.username }) { notification.post.user.name } - a.post-preview(href={ CONFIG.url + '/' + notification.post.user.username + '/' + notification.post.id }) { get-post-summary(notification.post) } - -style. - display block - margin 0 - padding 16px - - > mk-time - display inline - position absolute - top 16px - right 12px - vertical-align top - color rgba(0, 0, 0, 0.6) - font-size 12px - - > .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 +<mk-notification class="{ notification.type }"> + <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 }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/></a> + <div class="text"> + <p><i class="fa fa-thumbs-o-up"></i><a href="{ CONFIG.url + '/' + notification.user.username }">{ 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 }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/></a> + <div class="text"> + <p><i class="fa fa-retweet"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }">{ 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 }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/></a> + <div class="text"> + <p><i class="fa fa-quote-left"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }">{ 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 }"><img class="avatar" src="{ notification.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/></a> + <div class="text"> + <p><i class="fa fa-user-plus"></i><a href="{ CONFIG.url + '/' + notification.user.username }">{ 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 }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/></a> + <div class="text"> + <p><i class="fa fa-reply"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }">{ 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 }"><img class="avatar" src="{ notification.post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/></a> + <div class="text"> + <p><i class="fa fa-at"></i><a href="{ CONFIG.url + '/' + notification.post.user.username }">{ 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> + <style type="stylus"> + :scope + display block 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 - - .post-preview - color rgba(0, 0, 0, 0.7) - -script. - @mixin \get-post-summary - @notification = @opts.notification + padding 16px + + > mk-time + display inline + position absolute + top 16px + right 12px + vertical-align top + color rgba(0, 0, 0, 0.6) + font-size 12px + + > .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 + + .post-preview + color rgba(0, 0, 0, 0.7) + + </style> + <script> + @mixin \get-post-summary + @notification = @opts.notification + </script> +</mk-notification> diff --git a/src/web/app/mobile/tags/notifications.tag b/src/web/app/mobile/tags/notifications.tag index 7510d599679f5e3b86411c68eb2ff7a49ecdcafd..9ebe1dc5c8f1fb2c322b2041cf46567f768898dd 100644 --- a/src/web/app/mobile/tags/notifications.tag +++ b/src/web/app/mobile/tags/notifications.tag @@ -1,98 +1,93 @@ -mk-notifications - div.notifications(if={ notifications.length != 0 }) - virtual(each={ notification, i in notifications }) - mk-notification(notification={ notification }) - - 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 - background #fff - - > .notifications - margin 0 auto - max-width 500px - - > mk-notification - border-bottom solid 1px rgba(0, 0, 0, 0.05) - - &:last-child - border-bottom none - - > .date +<mk-notifications> + <div class="notifications" if="{ notifications.length != 0 }"> + <virtual each="{ notification, i in notifications }"> + <mk-notification notification="{ notification }"></mk-notification> + <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 - 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 \get-post-summary - - @notifications = [] - @loading = true - - @on \mount ~> - @api \i/notifications - .then (notifications) ~> - @notifications = notifications - @loading = false + background #fff + + > .notifications + margin 0 auto + max-width 500px + + > mk-notification + border-bottom solid 1px rgba(0, 0, 0, 0.05) + + &:last-child + border-bottom none + + > .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 + + </style> + <script> + @mixin \api + @mixin \stream + @mixin \get-post-summary + + @notifications = [] + @loading = true + + @on \mount ~> + @api \i/notifications + .then (notifications) ~> + @notifications = notifications + @loading = false + @update! + @trigger \loaded + .catch (err, text-status) -> + console.error err + + @stream.on \notification @on-notification + + @on \unmount ~> + @stream.off \notification @on-notification + + @on-notification = (notification) ~> + @notifications.unshift notification @update! - @trigger \loaded - .catch (err, text-status) -> - console.error err - @stream.on \notification @on-notification - - @on \unmount ~> - @stream.off \notification @on-notification - - @on-notification = (notification) ~> - @notifications.unshift notification - @update! - - @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 + 'æ—¥' + @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 + 'æ—¥' + </script> +</mk-notifications> diff --git a/src/web/app/mobile/tags/notify.tag b/src/web/app/mobile/tags/notify.tag index 9dd93ccf258edc9ba3258258a03e07688c0bcece..e50a1ef6c142902893ad93f2d96609d24560a73c 100644 --- a/src/web/app/mobile/tags/notify.tag +++ b/src/web/app/mobile/tags/notify.tag @@ -1,35 +1,38 @@ -mk-notify - mk-notification-preview(notification={ opts.notification }) +<mk-notify> + <mk-notification-preview notification="{ opts.notification }"></mk-notification-preview> + <style type="stylus"> + :scope + display block + position fixed + z-index 1024 + bottom -64px + left 0 + width 100% + height 64px + pointer-events none + -webkit-backdrop-filter blur(2px) + backdrop-filter blur(2px) + background-color rgba(#000, 0.5) -style. - display block - position fixed - z-index 1024 - bottom -64px - left 0 - width 100% - height 64px - pointer-events none - -webkit-backdrop-filter blur(2px) - backdrop-filter blur(2px) - background-color rgba(#000, 0.5) - -script. - @on \mount ~> - Velocity @root, { - bottom: \0px - } { - duration: 500ms - easing: \ease-out - } - - set-timeout ~> + </style> + <script> + @on \mount ~> Velocity @root, { - bottom: \-64px + bottom: \0px } { duration: 500ms easing: \ease-out - complete: ~> - @unmount! } - , 6000ms + + set-timeout ~> + Velocity @root, { + bottom: \-64px + } { + duration: 500ms + easing: \ease-out + complete: ~> + @unmount! + } + , 6000ms + </script> +</mk-notify> diff --git a/src/web/app/mobile/tags/page/drive.tag b/src/web/app/mobile/tags/page/drive.tag index 9bef7e6648f7fccc782963c41401467e5fc9379b..02287cecde4a163c3090b0bf0b1141cbca362afb 100644 --- a/src/web/app/mobile/tags/page/drive.tag +++ b/src/web/app/mobile/tags/page/drive.tag @@ -1,46 +1,51 @@ -mk-drive-page - mk-ui@ui: mk-drive@browser(folder={ parent.opts.folder }, file={ parent.opts.file }) - -style. - display block - -script. - @mixin \ui - @mixin \ui-progress - - @on \mount ~> - document.title = 'Misskey Drive' - @ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ' +<mk-drive-page> + <mk-ui ref="ui"> + <mk-drive ref="browser" folder="{ parent.opts.folder }" file="{ parent.opts.file }"></mk-drive> + </mk-ui> + <style type="stylus"> + :scope + display block + + </style> + <script> + @mixin \ui + @mixin \ui-progress + + @on \mount ~> + document.title = 'Misskey Drive' + @ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ' - @refs.ui.refs.browser.on \begin-load ~> - @Progress.start! + @refs.ui.refs.browser.on \begin-load ~> + @Progress.start! - @refs.ui.refs.browser.on \loaded-mid ~> - @Progress.set 0.5 + @refs.ui.refs.browser.on \loaded-mid ~> + @Progress.set 0.5 - @refs.ui.refs.browser.on \loaded ~> - @Progress.done! + @refs.ui.refs.browser.on \loaded ~> + @Progress.done! - @refs.ui.refs.browser.on \move-root ~> - @ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ' + @refs.ui.refs.browser.on \move-root ~> + @ui.trigger \title '<i class="fa fa-cloud"></i>ドライブ' - # Rewrite URL - history.push-state null null '/i/drive' + # Rewrite URL + history.push-state null null '/i/drive' - @refs.ui.refs.browser.on \cd (folder) ~> - # TODO: escape html characters in folder.name - @ui.trigger \title '<i class="fa fa-folder-open"></i>' + folder.name + @refs.ui.refs.browser.on \cd (folder) ~> + # TODO: escape html characters in folder.name + @ui.trigger \title '<i class="fa fa-folder-open"></i>' + folder.name - @refs.ui.refs.browser.on \move (folder) ~> - # Rewrite URL - history.push-state null null '/i/drive/folder/' + folder.id + @refs.ui.refs.browser.on \move (folder) ~> + # Rewrite URL + history.push-state null null '/i/drive/folder/' + folder.id - @refs.ui.refs.browser.on \open-file (file) ~> - # TODO: escape html characters in file.name - @ui.trigger \title '<mk-file-type-icon class="icon"></mk-file-type-icon>' + file.name + @refs.ui.refs.browser.on \open-file (file) ~> + # TODO: escape html characters in file.name + @ui.trigger \title '<mk-file-type-icon class="icon"></mk-file-type-icon>' + file.name - # Rewrite URL - history.push-state null null '/i/drive/file/' + file.id + # Rewrite URL + history.push-state null null '/i/drive/file/' + file.id - riot.mount \mk-file-type-icon do - file: file + riot.mount \mk-file-type-icon do + file: file + </script> +</mk-drive-page> diff --git a/src/web/app/mobile/tags/page/entrance.tag b/src/web/app/mobile/tags/page/entrance.tag index 67d8bc9bbf0d894dc36424fd56f290d7f3fe73b3..85910e8e8954421c0a92267a25afbee65f1036c1 100644 --- a/src/web/app/mobile/tags/page/entrance.tag +++ b/src/web/app/mobile/tags/page/entrance.tag @@ -1,57 +1,60 @@ -mk-entrance - main - img(src='/_/resources/title.svg', alt='Misskey') - - mk-entrance-signin(if={ mode == 'signin' }) - mk-entrance-signup(if={ mode == 'signup' }) - div.introduction(if={ mode == 'introduction' }) - mk-introduction - button(onclick={ signin }) ã‚ã‹ã£ãŸ - - footer - mk-copyright - -style. - display block - height 100% - - > main - display block - - > img +<mk-entrance> + <main><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> + <div class="introduction" if="{ mode == 'introduction' }"> + <mk-introduction></mk-introduction> + <button onclick="{ signin }">ã‚ã‹ã£ãŸ</button> + </div> + </main> + <footer> + <mk-copyright></mk-copyright> + </footer> + <style type="stylus"> + :scope display block - width 130px - height 120px - margin 0 auto + height 100% - > .introduction - max-width 300px - margin 0 auto - color #666 - - > button + > main display block - margin 16px auto 0 auto - - > footer - > mk-copyright - margin 0 - text-align center - line-height 64px - font-size 10px - color rgba(#000, 0.5) -script. - @mode = \signin + > img + display block + width 130px + height 120px + margin 0 auto + + > .introduction + max-width 300px + margin 0 auto + color #666 + + > button + display block + margin 16px auto 0 auto + + > footer + > mk-copyright + margin 0 + text-align center + line-height 64px + font-size 10px + color rgba(#000, 0.5) + + </style> + <script> + @mode = \signin - @signup = ~> - @mode = \signup - @update! + @signup = ~> + @mode = \signup + @update! - @signin = ~> - @mode = \signin - @update! + @signin = ~> + @mode = \signin + @update! - @introduction = ~> - @mode = \introduction - @update! + @introduction = ~> + @mode = \introduction + @update! + </script> +</mk-entrance> diff --git a/src/web/app/mobile/tags/page/entrance/signin.tag b/src/web/app/mobile/tags/page/entrance/signin.tag index 484c414e8ed12b680afbc5c4e9ed2f77ddbc0082..0c5efe620ffe8cdfa0a4e7a3057c752035a74d8d 100644 --- a/src/web/app/mobile/tags/page/entrance/signin.tag +++ b/src/web/app/mobile/tags/page/entrance/signin.tag @@ -1,45 +1,51 @@ -mk-entrance-signin - mk-signin - div.divider: span or - button.signup(onclick={ parent.signup }) æ–°è¦ç™»éŒ² - a.introduction(onclick={ parent.introduction }) Misskeyã«ã¤ã„㦠- -style. - display block - margin 0 auto - padding 0 8px - max-width 350px - text-align center - - > .signup - padding 16px - width 100% - font-size 1em - color #fff - background $theme-color - border-radius 3px - - > .divider - padding 16px 0 - text-align center - - &:after - content "" +<mk-entrance-signin> + <mk-signin></mk-signin> + <div class="divider"><span>or</span></div> + <button class="signup" onclick="{ parent.signup }">æ–°è¦ç™»éŒ²</button><a class="introduction" onclick="{ parent.introduction }">Misskeyã«ã¤ã„ã¦</a> + <style type="stylus"> + :scope display block - position absolute - top 50% - width 100% - height 1px - border-top solid 1px rgba(0, 0, 0, 0.1) - - > * - z-index 1 + margin 0 auto padding 0 8px - color rgba(0, 0, 0, 0.5) - background #fdfdfd - - > .introduction - display inline-block - margin-top 16px - font-size 12px - color #666 + max-width 350px + text-align center + + > .signup + padding 16px + width 100% + font-size 1em + color #fff + background $theme-color + border-radius 3px + + > .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 + + > .introduction + display inline-block + margin-top 16px + font-size 12px + color #666 + + + + + + </style> +</mk-entrance-signin> diff --git a/src/web/app/mobile/tags/page/entrance/signup.tag b/src/web/app/mobile/tags/page/entrance/signup.tag index a28f85e63485a5a772dbaf94d9a843f5e4c0dbb1..77dff97511c4b5c42d24cd8b0e3b844c3e36f9c0 100644 --- a/src/web/app/mobile/tags/page/entrance/signup.tag +++ b/src/web/app/mobile/tags/page/entrance/signup.tag @@ -1,35 +1,42 @@ -mk-entrance-signup - mk-signup - button.cancel(type='button', onclick={ parent.signin }, title='ã‚ャンセル'): i.fa.fa-times +<mk-entrance-signup> + <mk-signup></mk-signup> + <button class="cancel" type="button" onclick="{ parent.signin }" title="ã‚ャンセル"><i class="fa fa-times"></i></button> + <style type="stylus"> + :scope + display block + margin 0 auto + padding 0 8px + max-width 350px -style. - display block - margin 0 auto - padding 0 8px - max-width 350px + > .cancel + 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 + box-shadow none + background transparent + transition opacity 0.1s ease - > .cancel - 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 - box-shadow none - background transparent - transition opacity 0.1s ease + &:hover + color #555 - &:hover - color #555 + &:active + color #222 - &:active - color #222 + > i + padding 14px - > i - padding 14px + + + + + </style> +</mk-entrance-signup> diff --git a/src/web/app/mobile/tags/page/home.tag b/src/web/app/mobile/tags/page/home.tag index c8d77296525b2d54e9a69201e43927a8f2117071..eb53be6601d553c2733520c4bb24383d2cbef3ce 100644 --- a/src/web/app/mobile/tags/page/home.tag +++ b/src/web/app/mobile/tags/page/home.tag @@ -1,40 +1,45 @@ -mk-home-page - mk-ui@ui: mk-home@home - -style. - display block - -script. - @mixin \i - @mixin \ui - @mixin \ui-progress - @mixin \stream - @mixin \get-post-summary - - @unread-count = 0 - - @on \mount ~> - document.title = 'Misskey' - @ui.trigger \title '<i class="fa fa-home"></i>ホーム' +<mk-home-page> + <mk-ui ref="ui"> + <mk-home ref="home"></mk-home> + </mk-ui> + <style type="stylus"> + :scope + display block + + </style> + <script> + @mixin \i + @mixin \ui + @mixin \ui-progress + @mixin \stream + @mixin \get-post-summary + + @unread-count = 0 + + @on \mount ~> + document.title = 'Misskey' + @ui.trigger \title '<i class="fa fa-home"></i>ホーム' - @Progress.start! + @Progress.start! - @stream.on \post @on-stream-post - document.add-event-listener \visibilitychange @window-on-visibilitychange, false + @stream.on \post @on-stream-post + document.add-event-listener \visibilitychange @window-on-visibilitychange, false - @refs.ui.refs.home.on \loaded ~> - @Progress.done! + @refs.ui.refs.home.on \loaded ~> + @Progress.done! - @on \unmount ~> - @stream.off \post @on-stream-post - document.remove-event-listener \visibilitychange @window-on-visibilitychange + @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 + @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' + @window-on-visibilitychange = ~> + if !document.hidden + @unread-count = 0 + document.title = 'Misskey' + </script> +</mk-home-page> diff --git a/src/web/app/mobile/tags/page/new-post.tag b/src/web/app/mobile/tags/page/new-post.tag index 21e00fc1f998a67254569189e667967ab686e8dc..1b6f73875c61ce4191b1cba7ff268d1013793d82 100644 --- a/src/web/app/mobile/tags/page/new-post.tag +++ b/src/web/app/mobile/tags/page/new-post.tag @@ -1,5 +1,12 @@ -mk-new-post-page - mk-post-form@form +<mk-new-post-page> + <mk-post-form ref="form"></mk-post-form> + <style type="stylus"> + :scope + display block -style. - display block + + + + + </style> +</mk-new-post-page> diff --git a/src/web/app/mobile/tags/page/notifications.tag b/src/web/app/mobile/tags/page/notifications.tag index 9fb34dcd7567832c565fb6c0cca13017dd042795..666a076cb200bc5b26f8e9bfed5a826b689eccce 100644 --- a/src/web/app/mobile/tags/page/notifications.tag +++ b/src/web/app/mobile/tags/page/notifications.tag @@ -1,18 +1,23 @@ -mk-notifications-page - mk-ui@ui: mk-notifications@notifications +<mk-notifications-page> + <mk-ui ref="ui"> + <mk-notifications ref="notifications"></mk-notifications> + </mk-ui> + <style type="stylus"> + :scope + display block -style. - display block + </style> + <script> + @mixin \ui + @mixin \ui-progress -script. - @mixin \ui - @mixin \ui-progress + @on \mount ~> + document.title = 'Misskey | 通知' + @ui.trigger \title '<i class="fa fa-bell-o"></i>通知' - @on \mount ~> - document.title = 'Misskey | 通知' - @ui.trigger \title '<i class="fa fa-bell-o"></i>通知' + @Progress.start! - @Progress.start! - - @refs.ui.refs.notifications.on \loaded ~> - @Progress.done! + @refs.ui.refs.notifications.on \loaded ~> + @Progress.done! + </script> +</mk-notifications-page> diff --git a/src/web/app/mobile/tags/page/post.tag b/src/web/app/mobile/tags/page/post.tag index 1dc74d267aca580c19b4b8644e12d58380129044..40ba429ec42d851aafbb13af561ea66a2ad7fe32 100644 --- a/src/web/app/mobile/tags/page/post.tag +++ b/src/web/app/mobile/tags/page/post.tag @@ -1,31 +1,38 @@ -mk-post-page - mk-ui@ui: main: mk-post-detail@post(post={ parent.post }) - -style. - display block - - main - background #fff - - > mk-post-detail - width 100% - max-width 500px - margin 0 auto - -script. - @mixin \ui - @mixin \ui-progress - - @post = @opts.post - - @on \mount ~> - document.title = 'Misskey' - @ui.trigger \title '<i class="fa fa-sticky-note-o"></i>投稿' - - @Progress.start! - - @refs.ui.refs.post.on \post-fetched ~> - @Progress.set 0.5 - - @refs.ui.refs.post.on \loaded ~> - @Progress.done! +<mk-post-page> + <mk-ui ref="ui"> + <main> + <mk-post-detail ref="post" post="{ parent.post }"></mk-post-detail> + </main> + </mk-ui> + <style type="stylus"> + :scope + display block + + main + background #fff + + > mk-post-detail + width 100% + max-width 500px + margin 0 auto + + </style> + <script> + @mixin \ui + @mixin \ui-progress + + @post = @opts.post + + @on \mount ~> + document.title = 'Misskey' + @ui.trigger \title '<i class="fa fa-sticky-note-o"></i>投稿' + + @Progress.start! + + @refs.ui.refs.post.on \post-fetched ~> + @Progress.set 0.5 + + @refs.ui.refs.post.on \loaded ~> + @Progress.done! + </script> +</mk-post-page> diff --git a/src/web/app/mobile/tags/page/search.tag b/src/web/app/mobile/tags/page/search.tag index 20de271f731cefaaac5eaa6d78d65cb80e1d59ef..9dd1d4e92ad2a7b1d90d6de7bec851fd47517b68 100644 --- a/src/web/app/mobile/tags/page/search.tag +++ b/src/web/app/mobile/tags/page/search.tag @@ -1,19 +1,24 @@ -mk-search-page - mk-ui@ui: mk-search@search(query={ parent.opts.query }) +<mk-search-page> + <mk-ui ref="ui"> + <mk-search ref="search" query="{ parent.opts.query }"></mk-search> + </mk-ui> + <style type="stylus"> + :scope + display block -style. - display block + </style> + <script> + @mixin \ui + @mixin \ui-progress -script. - @mixin \ui - @mixin \ui-progress + @on \mount ~> + document.title = '検索: ' + @opts.query + ' | Misskey' + # TODO: クエリをHTMLエスケープ + @ui.trigger \title '<i class="fa fa-search"></i>' + @opts.query - @on \mount ~> - document.title = '検索: ' + @opts.query + ' | Misskey' - # TODO: クエリをHTMLエスケープ - @ui.trigger \title '<i class="fa fa-search"></i>' + @opts.query + @Progress.start! - @Progress.start! - - @refs.ui.refs.search.on \loaded ~> - @Progress.done! + @refs.ui.refs.search.on \loaded ~> + @Progress.done! + </script> +</mk-search-page> diff --git a/src/web/app/mobile/tags/page/user-followers.tag b/src/web/app/mobile/tags/page/user-followers.tag index e7e9a6fd1ecbd573139026d3f16881de977bea12..9809f7085fe7da8f2c2cd2aaba75e7800a006ed1 100644 --- a/src/web/app/mobile/tags/page/user-followers.tag +++ b/src/web/app/mobile/tags/page/user-followers.tag @@ -1,31 +1,36 @@ -mk-user-followers-page - mk-ui@ui: mk-user-followers@list(if={ !parent.fetching }, user={ parent.user }) - -style. - display block - -script. - @mixin \ui - @mixin \ui-progress - @mixin \api - - @fetching = true - @user = null - - @on \mount ~> - @Progress.start! - - @api \users/show do - username: @opts.user - .then (user) ~> - @user = user - @fetching = false - - document.title = user.name + 'ã®ãƒ•ã‚©ãƒãƒ¯ãƒ¼ | Misskey' - # TODO: ユーザーåをエスケープ - @ui.trigger \title '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'ã®ãƒ•ã‚©ãƒãƒ¼' - - @update! - - @refs.ui.refs.list.on \loaded ~> - @Progress.done! +<mk-user-followers-page> + <mk-ui ref="ui"> + <mk-user-followers ref="list" if="{ !parent.fetching }" user="{ parent.user }"></mk-user-followers> + </mk-ui> + <style type="stylus"> + :scope + display block + + </style> + <script> + @mixin \ui + @mixin \ui-progress + @mixin \api + + @fetching = true + @user = null + + @on \mount ~> + @Progress.start! + + @api \users/show do + username: @opts.user + .then (user) ~> + @user = user + @fetching = false + + document.title = user.name + 'ã®ãƒ•ã‚©ãƒãƒ¯ãƒ¼ | Misskey' + # TODO: ユーザーåをエスケープ + @ui.trigger \title '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'ã®ãƒ•ã‚©ãƒãƒ¼' + + @update! + + @refs.ui.refs.list.on \loaded ~> + @Progress.done! + </script> +</mk-user-followers-page> diff --git a/src/web/app/mobile/tags/page/user-following.tag b/src/web/app/mobile/tags/page/user-following.tag index a74ba97b7266e1734e99109bff8ebf6c1ecd9172..71070eb0daf9624931a379e4a65c21eb72a3d74f 100644 --- a/src/web/app/mobile/tags/page/user-following.tag +++ b/src/web/app/mobile/tags/page/user-following.tag @@ -1,31 +1,36 @@ -mk-user-following-page - mk-ui@ui: mk-user-following@list(if={ !parent.fetching }, user={ parent.user }) - -style. - display block - -script. - @mixin \ui - @mixin \ui-progress - @mixin \api - - @fetching = true - @user = null - - @on \mount ~> - @Progress.start! - - @api \users/show do - username: @opts.user - .then (user) ~> - @user = user - @fetching = false - - document.title = user.name + 'ã®ãƒ•ã‚©ãƒãƒ¼ | Misskey' - # TODO: ユーザーåをエスケープ - @ui.trigger \title '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'ã®ãƒ•ã‚©ãƒãƒ¼' - - @update! - - @refs.ui.refs.list.on \loaded ~> - @Progress.done! +<mk-user-following-page> + <mk-ui ref="ui"> + <mk-user-following ref="list" if="{ !parent.fetching }" user="{ parent.user }"></mk-user-following> + </mk-ui> + <style type="stylus"> + :scope + display block + + </style> + <script> + @mixin \ui + @mixin \ui-progress + @mixin \api + + @fetching = true + @user = null + + @on \mount ~> + @Progress.start! + + @api \users/show do + username: @opts.user + .then (user) ~> + @user = user + @fetching = false + + document.title = user.name + 'ã®ãƒ•ã‚©ãƒãƒ¼ | Misskey' + # TODO: ユーザーåをエスケープ + @ui.trigger \title '<img src="' + user.avatar_url + '?thumbnail&size=64">' + user.name + 'ã®ãƒ•ã‚©ãƒãƒ¼' + + @update! + + @refs.ui.refs.list.on \loaded ~> + @Progress.done! + </script> +</mk-user-following-page> diff --git a/src/web/app/mobile/tags/page/user.tag b/src/web/app/mobile/tags/page/user.tag index 9667abfd14a0accf57f237a5dcf42f40f4059c28..f6106c95ccbf99ddb2f5f7cd5ae6aa0d8517bf88 100644 --- a/src/web/app/mobile/tags/page/user.tag +++ b/src/web/app/mobile/tags/page/user.tag @@ -1,20 +1,25 @@ -mk-user-page - mk-ui@ui: mk-user@user(user={ parent.user }, page={ parent.opts.page }) +<mk-user-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. - display block + </style> + <script> + @mixin \ui + @mixin \ui-progress -script. - @mixin \ui - @mixin \ui-progress + @user = @opts.user - @user = @opts.user + @on \mount ~> + @Progress.start! - @on \mount ~> - @Progress.start! - - @refs.ui.refs.user.on \loaded (user) ~> - @Progress.done! - document.title = user.name + ' | Misskey' - # TODO: ユーザーåをエスケープ - @ui.trigger \title '<i class="fa fa-user"></i>' + user.name + @refs.ui.refs.user.on \loaded (user) ~> + @Progress.done! + document.title = user.name + ' | Misskey' + # TODO: ユーザーåをエスケープ + @ui.trigger \title '<i class="fa fa-user"></i>' + user.name + </script> +</mk-user-page> diff --git a/src/web/app/mobile/tags/post-detail.tag b/src/web/app/mobile/tags/post-detail.tag index c7eb091ce61897d64943c586584884c3f4a499c2..b8d8ec3d8deeb9bd85541cedd1c79981da4926e7 100644 --- a/src/web/app/mobile/tags/post-detail.tag +++ b/src/web/app/mobile/tags/post-detail.tag @@ -1,415 +1,409 @@ -mk-post-detail - - div.fetching(if={ fetching }) - mk-ellipsis-icon - - div.main(if={ !fetching }) - - button.read-more(if={ p.reply_to && p.reply_to.reply_to_id && context == null }, onclick={ load-context }, disabled={ loading-context }) - i.fa.fa-ellipsis-v(if={ !loading-context }) - i.fa.fa-spinner.fa-pulse(if={ loading-context }) - - div.context - virtual(each={ post in context }) - mk-post-preview(post={ post }) - - div.reply-to(if={ p.reply_to }) - mk-post-preview(post={ p.reply_to }) - - div.repost(if={ is-repost }) - p - a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }): img.avatar(src={ post.user.avatar_url + '?thumbnail&size=32' }, alt='avatar') - i.fa.fa-retweet - a.name(href={ CONFIG.url + '/' + post.user.username }) { post.user.name } - | ãŒRepost - - article - a.avatar-anchor(href={ CONFIG.url + '/' + p.user.username }) - img.avatar(src={ p.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - header - a.name(href={ CONFIG.url + '/' + p.user.username }) - | { p.user.name } - span.username - | @{ p.user.username } - div.body - div.text@text - div.media(if={ p.media }) - virtual(each={ file in p.media }) - img(src={ file.url + '?thumbnail&size=512' }, alt={ file.name }, title={ file.name }) - a.time(href={ url }) - mk-time(time={ p.created_at }, mode='detail') - footer - button(onclick={ reply }, title='返信') - i.fa.fa-reply - p.count(if={ p.replies_count > 0 }) { p.replies_count } - button(onclick={ repost }, title='Repost') - i.fa.fa-retweet - p.count(if={ p.repost_count > 0 }) { p.repost_count } - button(class={ liked: p.is_liked }, onclick={ like }, title='善哉') - i.fa.fa-thumbs-o-up - p.count(if={ p.likes_count > 0 }) { p.likes_count } - button(onclick={ NotImplementedException }): i.fa.fa-ellipsis-h - div.reposts-and-likes - div.reposts(if={ reposts && reposts.length > 0 }) - header - a { p.repost_count } - p Repost - ol.users - li.user(each={ reposts }) - a.avatar-anchor(href={ CONFIG.url + '/' + user.username }, title={ user.name }) - img.avatar(src={ user.avatar_url + '?thumbnail&size=32' }, alt='') - div.likes(if={ likes && likes.length > 0 }) - header - a { p.likes_count } - p ã„ã„ã - ol.users - li.user(each={ likes }) - a.avatar-anchor(href={ CONFIG.url + '/' + username }, title={ name }) - 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 - - > .fetching - padding 64px 0 - - > .main - - > .read-more +<mk-post-detail> + <div class="fetching" if="{ fetching }"> + <mk-ellipsis-icon></mk-ellipsis-icon> + </div> + <div class="main" if="{ !fetching }"> + <button class="read-more" if="{ p.reply_to && p.reply_to.reply_to_id && context == null }" 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"> + <virtual each="{ post in context }"> + <mk-post-preview post="{ post }"></mk-post-preview> + </virtual> + </div> + <div class="reply-to" if="{ p.reply_to }"> + <mk-post-preview post="{ p.reply_to }"></mk-post-preview> + </div> + <div class="repost" if="{ isRepost }"> + <p><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }"><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> + </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"/></a> + <header><a class="name" href="{ CONFIG.url + '/' + p.user.username }">{ p.user.name }</a><span class="username">@{ p.user.username }</span></header> + <div class="body"> + <div class="text" ref="text"></div> + <div class="media" if="{ p.media }"> + <virtual each="{ file in p.media }"><img src="{ file.url + '?thumbnail&size=512' }" alt="{ file.name }" title="{ file.name }"/></virtual> + </div> + </div><a class="time" href="{ url }"> + <mk-time time="{ p.created_at }" mode="detail"></mk-time></a> + <footer> + <button onclick="{ reply }" title="返信"><i class="fa fa-reply"></i> + <p class="count" if="{ p.replies_count > 0 }">{ p.replies_count }</p> + </button> + <button onclick="{ repost }" title="Repost"><i class="fa fa-retweet"></i> + <p class="count" if="{ p.repost_count > 0 }">{ p.repost_count }</p> + </button> + <button class="{ liked: p.is_liked }" onclick="{ like }" title="善哉"><i class="fa fa-thumbs-o-up"></i> + <p class="count" if="{ p.likes_count > 0 }">{ p.likes_count }</p> + </button> + <button onclick="{ NotImplementedException }"><i class="fa fa-ellipsis-h"></i></button> + </footer> + <div class="reposts-and-likes"> + <div class="reposts" if="{ reposts && reposts.length > 0 }"> + <header><a>{ p.repost_count }</a> + <p>Repost</p> + </header> + <ol class="users"> + <li class="user" each="{ reposts }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + user.username }" title="{ user.name }"><img class="avatar" src="{ user.avatar_url + '?thumbnail&size=32' }" alt=""/></a></li> + </ol> + </div> + <div class="likes" if="{ likes && likes.length > 0 }"> + <header><a>{ p.likes_count }</a> + <p>ã„ã„ã</p> + </header> + <ol class="users"> + <li class="user" each="{ likes }"><a class="avatar-anchor" href="{ CONFIG.url + '/' + username }" title="{ name }"><img class="avatar" src="{ avatar_url + '?thumbnail&size=32' }" alt=""/></a></li> + </ol> + </div> + </div> + </article> + <div class="replies"> + <virtual each="{ post in replies }"> + <mk-post-detail-sub post="{ post }"></mk-post-detail-sub> + </virtual> + </div> + </div> + <style type="stylus"> + :scope display block margin 0 - padding 10px 0 - width 100% - font-size 1em - text-align center - color #999 - cursor pointer - background #fafafa - outline none - border none - border-bottom solid 1px #eef0f2 - border-radius 6px 6px 0 0 - box-shadow none - - &:hover - background #f6f6f6 - - &:active - background #f0f0f0 - - &:disabled - 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 14px 16px 9px 16px - - @media (min-width 500px) - padding 28px 32px 18px 32px - - &:after - content "" - display block - clear both - - &:hover - > .main > footer > button - color #888 - - > .avatar-anchor - display block - - > .avatar - display block - width 54px - height 54px - margin 0 - border-radius 8px - vertical-align bottom + padding 0 - @media (min-width 500px) - width 60px - height 60px - - > header - position absolute - top 18px - left 80px - width calc(100% - 80px) - - @media (min-width 500px) - top 28px - left 108px - width calc(100% - 108px) - - > .name - display inline-block - margin 0 - color #777 - font-size 16px - font-weight bold - text-align left - text-decoration none + > .fetching + padding 64px 0 - &:hover - text-decoration underline + > .main - > .username + > .read-more display block - text-align left margin 0 - color #ccc + padding 10px 0 + width 100% + font-size 1em + text-align center + color #999 + cursor pointer + background #fafafa + outline none + border none + border-bottom solid 1px #eef0f2 + border-radius 6px 6px 0 0 + box-shadow none - > .body - padding 8px 0 + &:hover + background #f6f6f6 - > .text - cursor default - display block - margin 0 - padding 0 - word-wrap break-word - font-size 16px - color #717171 + &:active + background #f0f0f0 - @media (min-width 500px) - font-size 24px + &:disabled + color #ccc - > mk-url-preview - margin-top 8px + > .context + > * + border-bottom 1px solid #eef0f2 - > .media - > img - display block - max-width 100% + > .repost + color #9dbb00 + background linear-gradient(to bottom, #edfde2 0%, #fff 100%) - > .time - font-size 16px - color #c0c0c0 + > p + margin 0 + padding 16px 32px - > footer - font-size 1.2em + .avatar-anchor + display inline-block - > button - margin 0 28px 0 0 - padding 8px - background transparent - border none - box-shadow none - font-size 1em - color #ddd - cursor pointer + .avatar + vertical-align bottom + min-width 28px + min-height 28px + max-width 28px + max-height 28px + margin 0 8px 0 0 + border-radius 6px - &:hover - color #666 + i + margin-right 4px - > .count - display inline - margin 0 0 0 8px - color #999 + .name + font-weight bold - &.liked - color $theme-color + & + article + padding-top 8px - > .reposts-and-likes - display flex - justify-content center - padding 0 - margin 16px 0 + > .reply-to + border-bottom 1px solid #eef0f2 - &:empty - display none + > article + padding 14px 16px 9px 16px - > .reposts - > .likes - display flex - flex 1 1 - padding 0 - border-top solid 1px #F2EFEE + @media (min-width 500px) + padding 28px 32px 18px 32px - > header - flex 1 1 80px - max-width 80px - padding 8px 5px 0px 10px + &:after + content "" + display block + clear both - > a - display block - font-size 1.5em - line-height 1.4em + &:hover + > .main > footer > button + color #888 + + > .avatar-anchor + display block - > p + > .avatar display block + width 54px + height 54px margin 0 - font-size 0.7em - line-height 1em - font-weight normal - color #a0a2a5 + border-radius 8px + vertical-align bottom - > .users - display block - flex 1 1 - margin 0 - padding 10px 10px 10px 5px - list-style none + @media (min-width 500px) + width 60px + height 60px - > .user - display block - float left - margin 4px - padding 0 + > header + position absolute + top 18px + left 80px + width calc(100% - 80px) + + @media (min-width 500px) + top 28px + left 108px + width calc(100% - 108px) + + > .name + display inline-block + margin 0 + color #777 + font-size 16px + font-weight bold + text-align left + text-decoration none - > .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 - -script. - @mixin \api - @mixin \text - @mixin \get-post-summary - @mixin \open-post-form - - @fetching = true - @loading-context = false - @content = null - @post = null - - @on \mount ~> - @api \posts/show do - post_id: @opts.post - .then (post) ~> - @post = post - @is-repost = @post.repost? - @p = if @is-repost then @post.repost else @post - @summary = @get-post-summary @p - @trigger \loaded - @fetching = false - @update! - - if @p.text? - tokens = @analyze @p.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 - - # Get likes - @api \posts/likes do - post_id: @p.id - limit: 8 - .then (likes) ~> - @likes = likes - @update! + &:hover + text-decoration underline - # Get reposts - @api \posts/reposts do - post_id: @p.id - limit: 8 - .then (reposts) ~> - @reposts = reposts - @update! + > .username + display block + text-align left + margin 0 + color #ccc - # Get replies - @api \posts/replies do - post_id: @p.id - limit: 8 - .then (replies) ~> - @replies = replies - @update! + > .body + padding 8px 0 - @reply = ~> - @open-post-form do - reply: @p - - @repost = ~> - text = window.prompt '「' + @summary + 'ã€ã‚’Repost' - if text? - @api \posts/create do - repost_id: @p.id - text: if text == '' then undefined else text - - @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 + > .text + cursor default + display block + margin 0 + padding 0 + word-wrap break-word + font-size 16px + color #717171 + + @media (min-width 500px) + font-size 24px + + > mk-url-preview + margin-top 8px + + > .media + > img + display block + max-width 100% + + > .time + font-size 16px + color #c0c0c0 + + > footer + font-size 1.2em + + > button + margin 0 28px 0 0 + padding 8px + background transparent + border none + box-shadow none + font-size 1em + color #ddd + cursor pointer + + &:hover + color #666 + + > .count + display inline + margin 0 0 0 8px + color #999 + + &.liked + color $theme-color + + > .reposts-and-likes + display flex + justify-content center + padding 0 + margin 16px 0 + + &:empty + display none + + > .reposts + > .likes + display flex + flex 1 1 + padding 0 + border-top solid 1px #F2EFEE + + > header + flex 1 1 80px + max-width 80px + padding 8px 5px 0px 10px + + > a + display block + font-size 1.5em + line-height 1.4em + + > p + display block + 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 + + > .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 \get-post-summary + @mixin \open-post-form + + @fetching = true + @loading-context = false + @content = null + @post = null + + @on \mount ~> + @api \posts/show do + post_id: @opts.post + .then (post) ~> + @post = post + @is-repost = @post.repost? + @p = if @is-repost then @post.repost else @post + @summary = @get-post-summary @p + @trigger \loaded + @fetching = false @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! + if @p.text? + tokens = @analyze @p.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 + + # 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! + + @reply = ~> + @open-post-form do + reply: @p + + @repost = ~> + text = window.prompt '「' + @summary + 'ã€ã‚’Repost' + if text? + @api \posts/create do + repost_id: @p.id + text: if text == '' then undefined else text + + @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! + </script> +</mk-post-detail> diff --git a/src/web/app/mobile/tags/post-form.tag b/src/web/app/mobile/tags/post-form.tag index 759a0820b8222f1d6880ec4b688110293f760023..838de1fc48be32e7816189916557d29fee9d1294 100644 --- a/src/web/app/mobile/tags/post-form.tag +++ b/src/web/app/mobile/tags/post-form.tag @@ -1,254 +1,264 @@ -mk-post-form - header: div - button.cancel(onclick={ cancel }): i.fa.fa-times - div - span.text-count(class={ over: refs.text.value.length > 300 }) { 300 - refs.text.value.length } - button.submit(onclick={ post }) 投稿 - div.form - mk-post-preview(if={ opts.reply }, post={ opts.reply }) - textarea@text(disabled={ wait }, oninput={ update }, onkeypress={ onkeypress }, onpaste={ onpaste }, placeholder={ opts.reply ? 'ã“ã®æŠ•ç¨¿ã¸ã®è¿”ä¿¡...' : 'ã„ã¾ã©ã†ã—ã¦ã‚‹ï¼Ÿ' }) - div.attaches(if={ files.length != 0 }) - ul.files@attaches - li.file(each={ files }) - div.img(style='background-image: url({ url + "?thumbnail&size=64" })', title={ name }) - li.add(if={ files.length < 4 }, title='PCã‹ã‚‰ãƒ•ã‚¡ã‚¤ãƒ«ã‚’添付', onclick={ select-file }): i.fa.fa-plus - mk-uploader@uploader - button@upload(onclick={ select-file }): i.fa.fa-upload - button@drive(onclick={ select-file-from-drive }): i.fa.fa-cloud - input@file(type='file', accept='image/*', multiple, onchange={ change-file }) - -style. - display block - padding-top 50px - - > header - position fixed - z-index 1000 - top 0 - left 0 - width 100% - height 50px - background #fff - - > div - max-width 500px - margin 0 auto - - > .cancel - width 50px - line-height 50px - font-size 24px - color #555 - - > div - position absolute - top 0 - right 0 - - > .text-count - line-height 50px - color #657786 +<mk-post-form> + <header> + <div> + <button class="cancel" onclick="{ cancel }"><i class="fa fa-times"></i></button> + <div><span class="text-count { over: refs.text.value.length > 300 }">{ 300 - refs.text.value.length }</span> + <button class="submit" onclick="{ post }">投稿</button> + </div> + </div> + </header> + <div class="form"> + <mk-post-preview if="{ opts.reply }" post="{ opts.reply }"></mk-post-preview> + <textarea ref="text" disabled="{ wait }" oninput="{ update }" onkeypress="{ onkeypress }" onpaste="{ onpaste }" placeholder="{ opts.reply ? 'ã“ã®æŠ•ç¨¿ã¸ã®è¿”ä¿¡...' : 'ã„ã¾ã©ã†ã—ã¦ã‚‹ï¼Ÿ' }"></textarea> + <div class="attaches" if="{ files.length != 0 }"> + <ul class="files" ref="attaches"> + <li class="file" each="{ files }"> + <div class="img" style="background-image: url({ url + "?thumbnail&size=64" })" title="{ name }"></div> + </li> + <li class="add" if="{ files.length < 4 }" title="PCã‹ã‚‰ãƒ•ã‚¡ã‚¤ãƒ«ã‚’添付" onclick="{ selectFile }"><i class="fa fa-plus"></i></li> + </ul> + </div> + <mk-uploader ref="uploader"></mk-uploader> + <button ref="upload" onclick="{ selectFile }"><i class="fa fa-upload"></i></button> + <button ref="drive" onclick="{ selectFileFromDrive }"><i class="fa fa-cloud"></i></button> + <input ref="file" type="file" accept="image/*" multiple="multiple" onchange="{ changeFile }"/> + </div> + <style type="stylus"> + :scope + display block + padding-top 50px - > .submit - margin 8px - padding 0 16px - line-height 34px - color $theme-color-foreground - background $theme-color - border-radius 4px + > header + position fixed + z-index 1000 + top 0 + left 0 + width 100% + height 50px + background #fff + + > div + max-width 500px + margin 0 auto + + > .cancel + width 50px + line-height 50px + font-size 24px + color #555 + + > div + position absolute + top 0 + right 0 - &:disabled - opacity 0.7 + > .text-count + line-height 50px + color #657786 - > .form - max-width 500px - margin 0 auto + > .submit + margin 8px + padding 0 16px + line-height 34px + color $theme-color-foreground + background $theme-color + border-radius 4px - > mk-post-preview - padding 16px + &:disabled + opacity 0.7 - > .attaches + > .form + max-width 500px + margin 0 auto - > .files - display block - margin 0 - padding 4px - list-style none + > mk-post-preview + padding 16px - &:after - content "" - display block - clear both + > .attaches - > .file - display block - float left - margin 4px - padding 0 - cursor move - - &:hover > .remove + > .files 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 + 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 + + > [ref='file'] + display none + + > [ref='text'] 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 + padding 12px + margin 0 + width 100% + max-width 100% + min-width 100% + min-height 80px + font-size 16px + color #333 + border none + border-bottom solid 1px #ddd + border-radius 0 - > [ref='file'] - display none + &:disabled + opacity 0.5 - > [ref='text'] - display block - padding 12px - margin 0 - width 100% - max-width 100% - min-width 100% - min-height 80px - font-size 16px - color #333 - border none - border-bottom solid 1px #ddd - border-radius 0 - - &:disabled - opacity 0.5 - - > [ref='upload'] - > [ref='drive'] - display inline-block - padding 0 - margin 0 - width 48px - height 48px - font-size 20px - color #657786 - background transparent - outline none - border none - border-radius 0 - box-shadow none - -script. - @mixin \api - - @wait = false - @uploadings = [] - @files = [] - - @on \mount ~> - @refs.uploader.on \uploaded (file) ~> - @add-file file - - @refs.uploader.on \change-uploads (uploads) ~> - @trigger \change-uploading-files uploads - - @refs.text.focus! - - @onkeypress = (e) ~> - if (e.char-code == 10 || e.char-code == 13) && e.ctrl-key - @post! - else + > [ref='upload'] + > [ref='drive'] + display inline-block + padding 0 + margin 0 + width 48px + height 48px + font-size 20px + color #657786 + background transparent + outline none + border none + border-radius 0 + box-shadow none + + </style> + <script> + @mixin \api + + @wait = false + @uploadings = [] + @files = [] + + @on \mount ~> + @refs.uploader.on \uploaded (file) ~> + @add-file file + + @refs.uploader.on \change-uploads (uploads) ~> + @trigger \change-uploading-files uploads + + @refs.text.focus! + + @onkeypress = (e) ~> + if (e.char-code == 10 || e.char-code == 13) && e.ctrl-key + @post! + else + return true + + @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! return true - @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! - return true - - @select-file = ~> - @refs.file.click! - - @select-file-from-drive = ~> - browser = document.body.append-child document.create-element \mk-drive-selector - browser = riot.mount browser, do - multiple: true - .0 - browser.on \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 + @select-file = ~> + @refs.file.click! + + @select-file-from-drive = ~> + browser = document.body.append-child document.create-element \mk-drive-selector + browser = riot.mount browser, do + multiple: true + .0 + browser.on \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 + @update! + + @files.push file @trigger \change-files @files @update! - @files.push file - @trigger \change-files @files - @update! - - @post = ~> - @wait = true - - files = if @files? and @files.length > 0 - then @files.map (f) -> f.id - else undefined - - @api \posts/create do - text: @refs.text.value - media_ids: files - reply_to_id: if @opts.reply? then @opts.reply.id else undefined - .then (data) ~> - @trigger \post + @post = ~> + @wait = true + + files = if @files? and @files.length > 0 + then @files.map (f) -> f.id + else undefined + + @api \posts/create do + text: @refs.text.value + media_ids: files + reply_to_id: if @opts.reply? then @opts.reply.id else undefined + .then (data) ~> + @trigger \post + @unmount! + .catch (err) ~> + console.error err + #@opts.ui.trigger \notification 'Error!' + @wait = false + @update! + + @cancel = ~> + @trigger \cancel @unmount! - .catch (err) ~> - console.error err - #@opts.ui.trigger \notification 'Error!' - @wait = false - @update! - - @cancel = ~> - @trigger \cancel - @unmount! + </script> +</mk-post-form> diff --git a/src/web/app/mobile/tags/post-preview.tag b/src/web/app/mobile/tags/post-preview.tag index e15b2be244f9ed2e3528b8dd093d3b46f34844f0..71faab2b8501e3bd46009ae3737c796005b82ab1 100644 --- a/src/web/app/mobile/tags/post-preview.tag +++ b/src/web/app/mobile/tags/post-preview.tag @@ -1,89 +1,86 @@ -mk-post-preview - article - a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }) - img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.main - header - a.name(href={ CONFIG.url + '/' + post.user.username }) - | { post.user.name } - span.username - | @{ post.user.username } - a.time(href={ CONFIG.url + '/' + post.user.username + '/' + post.id }) - mk-time(time={ post.created_at }) - div.body - mk-sub-post-content.text(post={ post }) - -style. - display block - margin 0 - padding 0 - font-size 0.9em - background #fff +<mk-post-preview> + <article><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/></a> + <div class="main"> + <header><a class="name" href="{ CONFIG.url + '/' + post.user.username }">{ post.user.name }</a><span class="username">@{ post.user.username }</span><a class="time" href="{ CONFIG.url + '/' + post.user.username + '/' + post.id }"> + <mk-time time="{ post.created_at }"></mk-time></a></header> + <div class="body"> + <mk-sub-post-content class="text" post="{ post }"></mk-sub-post-content> + </div> + </div> + </article> + <style type="stylus"> + :scope + display block + margin 0 + padding 0 + font-size 0.9em + background #fff - > article + > article - &:after - content "" - display block - clear both + &:after + content "" + display block + clear both - &:hover - > .main > footer > button - color #888 + &:hover + > .main > footer > button + color #888 - > .avatar-anchor - display block - float left - margin 0 12px 0 0 + > .avatar-anchor + display block + float left + margin 0 12px 0 0 - > .avatar - display block - width 48px - height 48px - margin 0 - border-radius 8px - vertical-align bottom + > .avatar + display block + width 48px + height 48px + margin 0 + border-radius 8px + vertical-align bottom - > .main - float left - width calc(100% - 60px) + > .main + float left + width calc(100% - 60px) - > header - margin-bottom 4px - white-space nowrap + > header + margin-bottom 4px + white-space nowrap - > .name - display inline - margin 0 - padding 0 - color #607073 - font-size 1em - font-weight 700 - text-align left - text-decoration none + > .name + display inline + margin 0 + padding 0 + color #607073 + font-size 1em + font-weight 700 + text-align left + text-decoration none - &:hover - text-decoration underline + &:hover + text-decoration underline - > .username - text-align left - margin 0 0 0 8px - color #d1d8da + > .username + text-align left + margin 0 0 0 8px + color #d1d8da - > .time - position absolute - top 0 - right 0 - color #b2b8bb + > .time + position absolute + top 0 + right 0 + color #b2b8bb - > .body + > .body - > .text - cursor default - margin 0 - padding 0 - font-size 1.1em - color #717171 + > .text + cursor default + margin 0 + padding 0 + font-size 1.1em + color #717171 -script. - @post = @opts.post + </style> + <script>@post = @opts.post</script> +</mk-post-preview> diff --git a/src/web/app/mobile/tags/search-posts.tag b/src/web/app/mobile/tags/search-posts.tag index 4b1b12af2777e04632eb7acfd5bc3e21af45638b..c22d794b5b8c4b88a0ee070431976115c09b7e1b 100644 --- a/src/web/app/mobile/tags/search-posts.tag +++ b/src/web/app/mobile/tags/search-posts.tag @@ -1,29 +1,32 @@ -mk-search-posts - mk-timeline(init={ init }, more={ more }, empty={ '「' + query + 'ã€ã«é–¢ã™ã‚‹æŠ•ç¨¿ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚' }) +<mk-search-posts> + <mk-timeline init="{ init }" more="{ more }" empty="{ '「' + query + 'ã€ã«é–¢ã™ã‚‹æŠ•ç¨¿ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚' }"></mk-timeline> + <style type="stylus"> + :scope + display block + background #fff -style. - display block - background #fff + </style> + <script> + @mixin \api -script. - @mixin \api + @max = 30 + @offset = 0 - @max = 30 - @offset = 0 + @query = @opts.query + @with-media = @opts.with-media - @query = @opts.query - @with-media = @opts.with-media + @init = new Promise (res, rej) ~> + @api \posts/search do + query: @query + .then (posts) ~> + res posts + @trigger \loaded - @init = new Promise (res, rej) ~> - @api \posts/search do - query: @query - .then (posts) ~> - res posts - @trigger \loaded - - @more = ~> - @offset += @max - @api \posts/search do - query: @query - max: @max - offset: @offset + @more = ~> + @offset += @max + @api \posts/search do + query: @query + max: @max + offset: @offset + </script> +</mk-search-posts> diff --git a/src/web/app/mobile/tags/search.tag b/src/web/app/mobile/tags/search.tag index bf2299cc9bb8ad89c2e403fefd466788e7d2b761..bb0744147fdae27a67871d5f7d36cb17b8d45b92 100644 --- a/src/web/app/mobile/tags/search.tag +++ b/src/web/app/mobile/tags/search.tag @@ -1,12 +1,15 @@ -mk-search - mk-search-posts@posts(query={ query }) +<mk-search> + <mk-search-posts ref="posts" query="{ query }"></mk-search-posts> + <style type="stylus"> + :scope + display block -style. - display block + </style> + <script> + @query = @opts.query -script. - @query = @opts.query - - @on \mount ~> - @refs.posts.on \loaded ~> - @trigger \loaded + @on \mount ~> + @refs.posts.on \loaded ~> + @trigger \loaded + </script> +</mk-search> diff --git a/src/web/app/mobile/tags/stream-indicator.tag b/src/web/app/mobile/tags/stream-indicator.tag index 2eb5889ca6f8c7bb17bf8d20ca0af49275b5d5ca..4046f5fec43d850614027529199f571c1df6a3fe 100644 --- a/src/web/app/mobile/tags/stream-indicator.tag +++ b/src/web/app/mobile/tags/stream-indicator.tag @@ -1,59 +1,54 @@ -mk-stream-indicator - p(if={ state == 'initializing' }) - i.fa.fa-spinner.fa-spin - span - | æŽ¥ç¶šä¸ - mk-ellipsis - p(if={ state == 'reconnecting' }) - i.fa.fa-spinner.fa-spin - span - | 切æ–ã•ã‚Œã¾ã—ãŸ æŽ¥ç¶šä¸ - mk-ellipsis - p(if={ state == 'connected' }) - i.fa.fa-check - span 接続完了 - -style. - display block - pointer-events none - 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 - display block - margin 0 - - > i - margin-right 0.25em - -script. - @mixin \stream - - @on \before-mount ~> - @state = @get-stream-state! - - if @state == \connected - @root.style.opacity = 0 - - @stream-state-ev.on \connected ~> - @state = @get-stream-state! - @update! - set-timeout ~> +<mk-stream-indicator> + <p if="{ state == 'initializing' }"><i class="fa fa-spinner fa-spin"></i><span>æŽ¥ç¶šä¸ + <mk-ellipsis></mk-ellipsis></span></p> + <p if="{ state == 'reconnecting' }"><i class="fa fa-spinner fa-spin"></i><span>切æ–ã•ã‚Œã¾ã—ãŸ æŽ¥ç¶šä¸ + <mk-ellipsis></mk-ellipsis></span></p> + <p if="{ state == 'connected' }"><i class="fa fa-check"></i><span>接続完了</span></p> + <style type="stylus"> + :scope + display block + pointer-events none + 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 + display block + margin 0 + + > i + margin-right 0.25em + + </style> + <script> + @mixin \stream + + @on \before-mount ~> + @state = @get-stream-state! + + if @state == \connected + @root.style.opacity = 0 + + @stream-state-ev.on \connected ~> + @state = @get-stream-state! + @update! + set-timeout ~> + Velocity @root, { + opacity: 0 + } 200ms \linear + , 1000ms + + @stream-state-ev.on \closed ~> + @state = @get-stream-state! + @update! Velocity @root, { - opacity: 0 - } 200ms \linear - , 1000ms - - @stream-state-ev.on \closed ~> - @state = @get-stream-state! - @update! - Velocity @root, { - opacity: 1 - } 0ms + opacity: 1 + } 0ms + </script> +</mk-stream-indicator> diff --git a/src/web/app/mobile/tags/sub-post-content.tag b/src/web/app/mobile/tags/sub-post-content.tag index 595f63d79467a6ea664cb9fad95ec6f1fa913fd3..0f015fddfd8db32b3a04a05480d077c0c8138f4b 100644 --- a/src/web/app/mobile/tags/sub-post-content.tag +++ b/src/web/app/mobile/tags/sub-post-content.tag @@ -1,36 +1,37 @@ -mk-sub-post-content - div.body - a.reply(if={ post.reply_to_id }): i.fa.fa-reply - span@text - a.quote(if={ post.repost_id }, href={ '/post:' + post.repost_id }) RP: ... - details(if={ post.media }) - summary ({ post.media.length }æžšã®ç”»åƒ) - mk-images-viewer(images={ post.media }) +<mk-sub-post-content> + <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> + <details if="{ post.media }"> + <summary>({ post.media.length }æžšã®ç”»åƒ)</summary> + <mk-images-viewer images="{ post.media }"></mk-images-viewer> + </details> + <style type="stylus"> + :scope + display block + word-wrap break-word -style. - display block - word-wrap break-word + > .body + > .reply + margin-right 6px + color #717171 - > .body - > .reply - margin-right 6px - color #717171 + > .quote + margin-left 4px + font-style oblique + color #a0bf46 - > .quote - margin-left 4px - font-style oblique - color #a0bf46 + </style> + <script> + @mixin \text -script. - @mixin \text + @post = @opts.post - @post = @opts.post + @on \mount ~> + if @post.text? + tokens = @analyze @post.text + @refs.text.innerHTML = @compile tokens, false - @on \mount ~> - if @post.text? - tokens = @analyze @post.text - @refs.text.innerHTML = @compile tokens, false - - @refs.text.children.for-each (e) ~> - if e.tag-name == \MK-URL - riot.mount e + @refs.text.children.for-each (e) ~> + if e.tag-name == \MK-URL + riot.mount e + </script> +</mk-sub-post-content> diff --git a/src/web/app/mobile/tags/timeline-post-sub.tag b/src/web/app/mobile/tags/timeline-post-sub.tag index 920503ebcc33b2774c62b81e7b6ec1a5d8d23b1c..e6f9df2be6fef2bc8673a07cc304357ce54e7152 100644 --- a/src/web/app/mobile/tags/timeline-post-sub.tag +++ b/src/web/app/mobile/tags/timeline-post-sub.tag @@ -1,99 +1,96 @@ -mk-timeline-post-sub - article - a.avatar-anchor(href={ '/' + post.user.username }) - img.avatar(src={ post.user.avatar_url + '?thumbnail&size=96' }, alt='avatar') - div.main - header - a.name(href={ '/' + post.user.username }) - | { post.user.name } - span.username - | @{ post.user.username } - a.created-at(href={ '/' + post.user.username + '/' + post.id }) - mk-time(time={ post.created_at }) - div.body - mk-sub-post-content.text(post={ post }) - -style. - display block - margin 0 - padding 0 - font-size 0.9em - - > article - padding 16px - - &:after - content "" +<mk-timeline-post-sub> + <article><a class="avatar-anchor" href="{ '/' + post.user.username }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&size=96' }" alt="avatar"/></a> + <div class="main"> + <header><a class="name" href="{ '/' + post.user.username }">{ post.user.name }</a><span class="username">@{ post.user.username }</span><a class="created-at" href="{ '/' + post.user.username + '/' + post.id }"> + <mk-time time="{ post.created_at }"></mk-time></a></header> + <div class="body"> + <mk-sub-post-content class="text" post="{ post }"></mk-sub-post-content> + </div> + </div> + </article> + <style type="stylus"> + :scope display block - clear both - - &:hover - > .main > footer > button - color #888 - - > .avatar-anchor - display block - float left - margin 0 10px 0 0 - - @media (min-width 500px) - margin-right 16px - - > .avatar - display block - width 44px - height 44px - margin 0 - border-radius 8px - vertical-align bottom - - @media (min-width 500px) - width 52px - height 52px - - > .main - float left - width calc(100% - 54px) - - @media (min-width 500px) - width calc(100% - 68px) - - > header - margin-bottom 4px - white-space nowrap - - > .name - display inline - margin 0 - padding 0 - color #607073 - 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 #d1d8da - - > .created-at - position absolute - top 0 - right 0 - color #b2b8bb - - > .body - - > .text - cursor default - margin 0 - padding 0 - font-size 1.1em - color #717171 - -script. - @post = @opts.post + margin 0 + padding 0 + font-size 0.9em + + > article + padding 16px + + &:after + content "" + display block + clear both + + &:hover + > .main > footer > button + color #888 + + > .avatar-anchor + display block + float left + margin 0 10px 0 0 + + @media (min-width 500px) + margin-right 16px + + > .avatar + display block + width 44px + height 44px + margin 0 + border-radius 8px + vertical-align bottom + + @media (min-width 500px) + width 52px + height 52px + + > .main + float left + width calc(100% - 54px) + + @media (min-width 500px) + width calc(100% - 68px) + + > header + margin-bottom 4px + white-space nowrap + + > .name + display inline + margin 0 + padding 0 + color #607073 + 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 #d1d8da + + > .created-at + position absolute + top 0 + right 0 + color #b2b8bb + + > .body + + > .text + cursor default + margin 0 + padding 0 + font-size 1.1em + color #717171 + + </style> + <script>@post = @opts.post</script> +</mk-timeline-post-sub> diff --git a/src/web/app/mobile/tags/timeline-post.tag b/src/web/app/mobile/tags/timeline-post.tag index a71fab26f028b5826df93b96748babb2ac64d43c..3037b4bef3934edaca5a3084ca8de1c16b1b7600 100644 --- a/src/web/app/mobile/tags/timeline-post.tag +++ b/src/web/app/mobile/tags/timeline-post.tag @@ -1,296 +1,291 @@ -mk-timeline-post(class={ repost: is-repost }) - - div.reply-to(if={ p.reply_to }) - mk-timeline-post-sub(post={ p.reply_to }) - - div.repost(if={ is-repost }) - p - a.avatar-anchor(href={ CONFIG.url + '/' + post.user.username }): img.avatar(src={ post.user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - i.fa.fa-retweet - a.name(href={ CONFIG.url + '/' + post.user.username }) { post.user.name } - | ãŒRepost - mk-time(time={ post.created_at }) - - article - a.avatar-anchor(href={ CONFIG.url + '/' + p.user.username }) - img.avatar(src={ p.user.avatar_url + '?thumbnail&size=96' }, alt='avatar') - div.main - header - a.name(href={ CONFIG.url + '/' + p.user.username }) - | { p.user.name } - span.username - | @{ p.user.username } - a.created-at(href={ url }) - mk-time(time={ p.created_at }) - div.body - div.text - a.reply(if={ p.reply_to }): i.fa.fa-reply - soan@text - a.quote(if={ p.repost != null }) RP: - div.media(if={ p.media }) - mk-images-viewer(images={ p.media }) - div.repost(if={ p.repost }) - i.fa.fa-quote-right.fa-flip-horizontal - mk-post-preview.repost(post={ p.repost }) - footer - button(onclick={ reply }) - i.fa.fa-reply - p.count(if={ p.replies_count > 0 }) { p.replies_count } - button(onclick={ repost }, title='Repost') - i.fa.fa-retweet - p.count(if={ p.repost_count > 0 }) { p.repost_count } - button(class={ liked: p.is_liked }, onclick={ like }) - i.fa.fa-thumbs-o-up - p.count(if={ p.likes_count > 0 }) { p.likes_count } - -style. - display block - margin 0 - padding 0 - font-size 12px - - @media (min-width 350px) - font-size 14px - - @media (min-width 500px) - font-size 16px - - > .repost - color #9dbb00 - background linear-gradient(to bottom, #edfde2 0%, #fff 100%) - - > p +<mk-timeline-post class="{ repost: isRepost }"> + <div class="reply-to" if="{ p.reply_to }"> + <mk-timeline-post-sub post="{ p.reply_to }"></mk-timeline-post-sub> + </div> + <div class="repost" if="{ isRepost }"> + <p><a class="avatar-anchor" href="{ CONFIG.url + '/' + post.user.username }"><img class="avatar" src="{ post.user.avatar_url + '?thumbnail&size=64' }" 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-time time="{ post.created_at }"></mk-time> + </div> + <article><a class="avatar-anchor" href="{ CONFIG.url + '/' + p.user.username }"><img class="avatar" src="{ p.user.avatar_url + '?thumbnail&size=96' }" alt="avatar"/></a> + <div class="main"> + <header><a class="name" href="{ CONFIG.url + '/' + p.user.username }">{ p.user.name }</a><span class="username">@{ p.user.username }</span><a class="created-at" href="{ url }"> + <mk-time time="{ p.created_at }"></mk-time></a></header> + <div class="body"> + <div class="text"><a class="reply" if="{ p.reply_to }"><i class="fa fa-reply"></i></a> + <soan ref="text"></soan><a class="quote" if="{ p.repost != null }">RP:</a> + </div> + <div class="media" if="{ p.media }"> + <mk-images-viewer images="{ p.media }"></mk-images-viewer> + </div> + <div class="repost" if="{ p.repost }"><i class="fa fa-quote-right fa-flip-horizontal"></i> + <mk-post-preview class="repost" post="{ p.repost }"></mk-post-preview> + </div> + </div> + <footer> + <button onclick="{ reply }"><i class="fa fa-reply"></i> + <p class="count" if="{ p.replies_count > 0 }">{ p.replies_count }</p> + </button> + <button onclick="{ repost }" title="Repost"><i class="fa fa-retweet"></i> + <p class="count" if="{ p.repost_count > 0 }">{ p.repost_count }</p> + </button> + <button class="{ liked: p.is_liked }" onclick="{ like }"><i class="fa fa-thumbs-o-up"></i> + <p class="count" if="{ p.likes_count > 0 }">{ p.likes_count }</p> + </button> + </footer> + </div> + </article> + <style type="stylus"> + :scope + display block margin 0 - padding 8px 16px - line-height 28px - - @media (min-width 500px) - padding 16px - - .avatar-anchor - display inline-block + padding 0 + font-size 12px - .avatar - vertical-align bottom - width 28px - height 28px - margin 0 8px 0 0 - border-radius 6px - - i - margin-right 4px - - .name - font-weight bold - - > mk-time - position absolute - top 8px - right 16px - font-size 0.9em - line-height 28px + @media (min-width 350px) + font-size 14px @media (min-width 500px) - top 16px - - & + article - padding-top 8px - - > .reply-to - background rgba(0, 0, 0, 0.0125) - - > mk-post-preview - background transparent - - > article - padding 14px 16px 9px 16px - - &:after - content "" - display block - clear both - - > .avatar-anchor - display block - float left - margin 0 10px 0 0 + font-size 16px - @media (min-width 500px) - margin-right 16px + > .repost + color #9dbb00 + background linear-gradient(to bottom, #edfde2 0%, #fff 100%) - > .avatar - display block - width 48px - height 48px - margin 0 - border-radius 6px - vertical-align bottom + > p + margin 0 + padding 8px 16px + line-height 28px - @media (min-width 500px) - width 58px - height 58px - border-radius 8px + @media (min-width 500px) + padding 16px - > .main - float left - width calc(100% - 58px) + .avatar-anchor + display inline-block - @media (min-width 500px) - width calc(100% - 74px) + .avatar + vertical-align bottom + width 28px + height 28px + margin 0 8px 0 0 + border-radius 6px - > header - white-space nowrap + i + margin-right 4px - @media (min-width 500px) - margin-bottom 2px + .name + font-weight bold - > .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 + > mk-time position absolute - top 0 - right 0 + top 8px + right 16px font-size 0.9em - color #c0c0c0 - - > .body + line-height 28px - > .text - cursor default - display block - margin 0 - padding 0 - word-wrap break-word - font-size 1.1em - color #717171 + @media (min-width 500px) + top 16px - mk-url-preview - margin-top 8px + & + article + padding-top 8px - > .reply - margin-right 8px - color #717171 + > .reply-to + background rgba(0, 0, 0, 0.0125) - > .quote - margin-left 4px - font-style oblique - color #a0bf46 + > mk-post-preview + background transparent - > .media - > img - display block - max-width 100% + > article + padding 14px 16px 9px 16px - > .repost - margin 8px 0 + &:after + content "" + display block + clear both - > i:first-child - position absolute - top -8px - left -8px - z-index 1 - color #c0dac6 - font-size 28px - background #fff + > .avatar-anchor + display block + float left + margin 0 10px 0 0 - > mk-post-preview - padding 16px - border dashed 1px #c0dac6 - border-radius 8px + @media (min-width 500px) + margin-right 16px - > footer - > button - margin 0 28px 0 0 - padding 8px - background transparent - border none - box-shadow none - font-size 1em - color #ddd - cursor pointer - - &:hover - color #666 - - > .count - display inline - margin 0 0 0 8px - color #999 - - &.liked - color $theme-color - -script. - @mixin \api - @mixin \text - @mixin \get-post-summary - @mixin \open-post-form - - @post = @opts.post - @is-repost = @post.repost? and !@post.text? - @p = if @is-repost then @post.repost else @post - @summary = @get-post-summary @p - @url = CONFIG.url + '/' + @p.user.username + '/' + @p.id - - @on \mount ~> - if @p.text? - tokens = if @p._highlight? - then @analyze @p._highlight - 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 = ~> - @open-post-form do - reply: @p - - @repost = ~> - text = window.prompt '「' + @summary + 'ã€ã‚’Repost' - if text? - @api \posts/create do - repost_id: @p.id - text: if text == '' then undefined else text - - @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! + > .avatar + display block + width 48px + height 48px + margin 0 + border-radius 6px + vertical-align bottom + + @media (min-width 500px) + width 58px + height 58px + border-radius 8px + + > .main + float left + width calc(100% - 58px) + + @media (min-width 500px) + width calc(100% - 74px) + + > header + white-space nowrap + + @media (min-width 500px) + margin-bottom 2px + + > .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 + top 0 + right 0 + font-size 0.9em + color #c0c0c0 + + > .body + + > .text + cursor default + display block + margin 0 + padding 0 + word-wrap break-word + font-size 1.1em + color #717171 + + mk-url-preview + margin-top 8px + + > .reply + margin-right 8px + color #717171 + + > .quote + margin-left 4px + font-style oblique + color #a0bf46 + + > .media + > img + display block + max-width 100% + + > .repost + margin 8px 0 + + > i:first-child + position absolute + top -8px + left -8px + z-index 1 + color #c0dac6 + font-size 28px + background #fff + + > mk-post-preview + padding 16px + border dashed 1px #c0dac6 + border-radius 8px + + > footer + > button + margin 0 28px 0 0 + padding 8px + background transparent + border none + box-shadow none + font-size 1em + color #ddd + cursor pointer + + &:hover + color #666 + + > .count + display inline + margin 0 0 0 8px + color #999 + + &.liked + color $theme-color + + </style> + <script> + @mixin \api + @mixin \text + @mixin \get-post-summary + @mixin \open-post-form + + @post = @opts.post + @is-repost = @post.repost? and !@post.text? + @p = if @is-repost then @post.repost else @post + @summary = @get-post-summary @p + @url = CONFIG.url + '/' + @p.user.username + '/' + @p.id + + @on \mount ~> + if @p.text? + tokens = if @p._highlight? + then @analyze @p._highlight + 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 = ~> + @open-post-form do + reply: @p + + @repost = ~> + text = window.prompt '「' + @summary + 'ã€ã‚’Repost' + if text? + @api \posts/create do + repost_id: @p.id + text: if text == '' then undefined else text + + @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! + </script> +</mk-timeline-post> diff --git a/src/web/app/mobile/tags/timeline.tag b/src/web/app/mobile/tags/timeline.tag index 711482487233ac82b92147e1286c732943ca468d..cef05d54a0187e971bdc5edfc4eeeb35357df583 100644 --- a/src/web/app/mobile/tags/timeline.tag +++ b/src/web/app/mobile/tags/timeline.tag @@ -1,128 +1,120 @@ -mk-timeline - div.init(if={ init }) - i.fa.fa-spinner.fa-pulse - | èªã¿è¾¼ã‚“ã§ã„ã¾ã™ - div.empty(if={ !init && posts.length == 0 }) - i.fa.fa-comments-o - | { opts.empty || '表示ã™ã‚‹ã‚‚ã®ãŒã‚ã‚Šã¾ã›ã‚“' } - virtual(each={ post, i in posts }) - mk-timeline-post(post={ post }) - p.date(if={ i != posts.length - 1 && post._date != posts[i + 1]._date }) - span - i.fa.fa-angle-up - | { post._datetext } - span - i.fa.fa-angle-down - | { posts[i + 1]._datetext } - footer(if={ !init }) - button(if={ can-fetch-more }, onclick={ more }, disabled={ fetching }) - span(if={ !fetching }) ã‚‚ã£ã¨ã¿ã‚‹ - span(if={ fetching }) - | èªã¿è¾¼ã¿ä¸ - mk-ellipsis - -style. - display block - background #fff - background-clip content-box - overflow hidden - - > .init - padding 64px 0 - text-align center - color #999 - - > i - margin-right 4px - - > .empty - margin 0 auto - padding 32px - max-width 400px - text-align center - color #999 - - > i +<mk-timeline> + <div class="init" if="{ init }"><i class="fa fa-spinner fa-pulse"></i>èªã¿è¾¼ã‚“ã§ã„ã¾ã™</div> + <div class="empty" if="{ !init && posts.length == 0 }"><i class="fa fa-comments-o"></i>{ opts.empty || '表示ã™ã‚‹ã‚‚ã®ãŒã‚ã‚Šã¾ã›ã‚“' }</div> + <virtual each="{ post, i in posts }"> + <mk-timeline-post post="{ post }"></mk-timeline-post> + <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> + </virtual> + <footer if="{ !init }"> + <button if="{ canFetchMore }" onclick="{ more }" disabled="{ fetching }"><span if="{ !fetching }">ã‚‚ã£ã¨ã¿ã‚‹</span><span if="{ fetching }">èªã¿è¾¼ã¿ä¸ + <mk-ellipsis></mk-ellipsis></span></button> + </footer> + <style type="stylus"> + :scope display block - margin-bottom 16px - font-size 3em - color #ccc - - > mk-timeline-post - border-bottom solid 1px #eaeaea - - &:last-of-type - border-bottom none - - > .date - display block - margin 0 - line-height 32px - text-align center - font-size 0.9em - color #aaa - background #fdfdfd - border-bottom solid 1px #eaeaea - - span - margin 0 16px - - i - margin-right 8px - - > footer - text-align center - border-top solid 1px #eaeaea - border-bottom-left-radius 4px - border-bottom-right-radius 4px - - > button - margin 0 - padding 16px - width 100% - color $theme-color - - &:disabled - opacity 0.7 - -script. - @posts = [] - @init = true - @fetching = false - @can-fetch-more = true - - @on \mount ~> - @opts.init.then (posts) ~> - @init = false - @set-posts posts - - @on \update ~> - @posts.for-each (post) ~> - date = (new Date post.created_at).get-date! - month = (new Date post.created_at).get-month! + 1 - post._date = date - post._datetext = month + '月 ' + date + 'æ—¥' - - @more = ~> - if @init or @fetching or @posts.length == 0 then return - @fetching = true - @update! - @opts.more!.then (posts) ~> - @fetching = false - @prepend-posts posts - - @set-posts = (posts) ~> - @posts = posts - @update! - - @prepend-posts = (posts) ~> - posts.for-each (post) ~> - @posts.push post + background #fff + background-clip content-box + overflow hidden + + > .init + padding 64px 0 + text-align center + color #999 + + > i + margin-right 4px + + > .empty + margin 0 auto + padding 32px + max-width 400px + text-align center + color #999 + + > i + display block + margin-bottom 16px + font-size 3em + color #ccc + + > mk-timeline-post + border-bottom solid 1px #eaeaea + + &:last-of-type + border-bottom none + + > .date + display block + margin 0 + line-height 32px + text-align center + font-size 0.9em + color #aaa + background #fdfdfd + border-bottom solid 1px #eaeaea + + span + margin 0 16px + + i + margin-right 8px + + > footer + text-align center + border-top solid 1px #eaeaea + border-bottom-left-radius 4px + border-bottom-right-radius 4px + + > button + margin 0 + padding 16px + width 100% + color $theme-color + + &:disabled + opacity 0.7 + + </style> + <script> + @posts = [] + @init = true + @fetching = false + @can-fetch-more = true + + @on \mount ~> + @opts.init.then (posts) ~> + @init = false + @set-posts posts + + @on \update ~> + @posts.for-each (post) ~> + date = (new Date post.created_at).get-date! + month = (new Date post.created_at).get-month! + 1 + post._date = date + post._datetext = month + '月 ' + date + 'æ—¥' + + @more = ~> + if @init or @fetching or @posts.length == 0 then return + @fetching = true @update! + @opts.more!.then (posts) ~> + @fetching = false + @prepend-posts posts - @add-post = (post) ~> - @posts.unshift post - @update! + @set-posts = (posts) ~> + @posts = posts + @update! + + @prepend-posts = (posts) ~> + posts.for-each (post) ~> + @posts.push post + @update! + + @add-post = (post) ~> + @posts.unshift post + @update! - @tail = ~> - @posts[@posts.length - 1] + @tail = ~> + @posts[@posts.length - 1] + </script> +</mk-timeline> diff --git a/src/web/app/mobile/tags/ui-header.tag b/src/web/app/mobile/tags/ui-header.tag index 7105d065f82fb42ae0831e7fa40841af647f3ad3..273b03213e5dec051bba4e94d0580bedbc87dec1 100644 --- a/src/web/app/mobile/tags/ui-header.tag +++ b/src/web/app/mobile/tags/ui-header.tag @@ -1,98 +1,103 @@ -mk-ui-header - mk-special-message - div.main - div.backdrop - div.content - button.nav#hamburger: i.fa.fa-bars - h1@title Misskey - button.post(onclick={ post }): i.fa.fa-pencil +<mk-ui-header> + <mk-special-message></mk-special-message> + <div class="main"> + <div class="backdrop"></div> + <div class="content"> + <button class="nav" id="hamburger"><i class="fa fa-bars"></i></button> + <h1 ref="title">Misskey</h1> + <button class="post" onclick="{ post }"><i class="fa fa-pencil"></i></button> + </div> + </div> + <style type="stylus"> + :scope + $height = 48px -style. - $height = 48px - - display block - position fixed - top 0 - z-index 1024 - width 100% - box-shadow 0 1px 0 rgba(#000, 0.075) - - > .main - color rgba(#000, 0.6) - - > .backdrop - position absolute + display block + position fixed top 0 - z-index 1023 + z-index 1024 width 100% - height $height - -webkit-backdrop-filter blur(12px) - backdrop-filter blur(12px) - background-color rgba(#fff, 0.75) + box-shadow 0 1px 0 rgba(#000, 0.075) - > .content - z-index 1024 + > .main + color rgba(#000, 0.6) + + > .backdrop + position absolute + top 0 + z-index 1023 + width 100% + height $height + -webkit-backdrop-filter blur(12px) + backdrop-filter blur(12px) + background-color rgba(#fff, 0.75) + + > .content + z-index 1024 - > h1 - display block - margin 0 auto - padding 0 - width 100% - max-width calc(100% - 112px) - text-align center - font-size 1.1em - font-weight normal - line-height $height - white-space nowrap - overflow hidden - text-overflow ellipsis + > h1 + display block + margin 0 auto + padding 0 + width 100% + max-width calc(100% - 112px) + text-align center + font-size 1.1em + font-weight normal + line-height $height + white-space nowrap + overflow hidden + text-overflow ellipsis - > i - margin-right 8px + > i + margin-right 8px - > img - display inline-block - vertical-align bottom - width ($height - 16px) - height ($height - 16px) - margin 8px - border-radius 6px + > img + display inline-block + vertical-align bottom + width ($height - 16px) + height ($height - 16px) + margin 8px + border-radius 6px - > .nav - display block - position absolute - top 0 - left 0 - width $height - font-size 1.4em - line-height $height - border-right solid 1px rgba(#000, 0.1) + > .nav + display block + position absolute + top 0 + left 0 + width $height + font-size 1.4em + line-height $height + border-right solid 1px rgba(#000, 0.1) - > i - transition all 0.2s ease + > i + transition all 0.2s ease - > .post - display block - position absolute - top 0 - right 0 - width $height - text-align center - font-size 1.4em - color inherit - line-height $height - border-left solid 1px rgba(#000, 0.1) + > .post + display block + position absolute + top 0 + right 0 + width $height + text-align center + font-size 1.4em + color inherit + line-height $height + border-left solid 1px rgba(#000, 0.1) -script. - @mixin \ui - @mixin \open-post-form + </style> + <script> + @mixin \ui + @mixin \open-post-form - @on \mount ~> - @opts.ready! + @on \mount ~> + @opts.ready! - @ui.one \title (title) ~> - if @refs.title? - @refs.title.innerHTML = title + @ui.one \title (title) ~> + if @refs.title? + @refs.title.innerHTML = title - @post = ~> - @open-post-form! + @post = ~> + @open-post-form! + </script> +</mk-ui-header> diff --git a/src/web/app/mobile/tags/ui-nav.tag b/src/web/app/mobile/tags/ui-nav.tag index 2c551b30ad12acb748d34187f7f68d6c43777a9d..de9c17cc8f5a38db589a3b33416f5e7813f404e5 100644 --- a/src/web/app/mobile/tags/ui-nav.tag +++ b/src/web/app/mobile/tags/ui-nav.tag @@ -1,169 +1,151 @@ -mk-ui-nav - div.body: div.content - a.me(if={ SIGNIN }, href={ CONFIG.url + '/' + I.username }) - img.avatar(src={ I.avatar_url + '?thumbnail&size=128' }, alt='avatar') - p.name { I.name } - div.links - ul - li.post: a(href='/i/post') - i.icon.fa.fa-pencil-square-o - | æ–°è¦æŠ•ç¨¿ - i.angle.fa.fa-angle-right - ul - li.home: a(href='/') - i.icon.fa.fa-home - | ホーム- i.angle.fa.fa-angle-right - li.mentions: a(href='/i/mentions') - i.icon.fa.fa-at - | ã‚ãªãŸå®›ã¦ - i.angle.fa.fa-angle-right - li.notifications: a(href='/i/notifications') - i.icon.fa.fa-bell-o - | 通知 - i.angle.fa.fa-angle-right - li.messaging: a - i.icon.fa.fa-comments-o - | メッセージ - i.angle.fa.fa-angle-right - ul - li.settings: a(onclick={ search }) - i.icon.fa.fa-search - | 検索 - i.angle.fa.fa-angle-right - ul - li.settings: a(href='/i/drive') - i.icon.fa.fa-cloud - | ドライブ - i.angle.fa.fa-angle-right - li.settings: a(href='/i/upload') - i.icon.fa.fa-upload - | アップãƒãƒ¼ãƒ‰ - i.angle.fa.fa-angle-right - ul - li.settings: a(href='/i/settings') - i.icon.fa.fa-cog - | è¨å®š - i.angle.fa.fa-angle-right - p.about - a Misskeyã«ã¤ã„㦠- -style. - display block - position fixed - top 0 - left 0 - z-index -1 - width 240px - color #fff - background #313538 - visibility hidden - - .body - height 100% - overflow hidden - - .content - min-height 100% - - .me - display block - margin 0 - padding 16px - - .avatar - display inline - max-width 64px - border-radius 32px - vertical-align middle - - .name +<mk-ui-nav> + <div class="body"> + <div class="content"><a class="me" if="{ SIGNIN }" href="{ CONFIG.url + '/' + I.username }"><img class="avatar" src="{ I.avatar_url + '?thumbnail&size=128' }" alt="avatar"/> + <p class="name">{ I.name }</p></a> + <div class="links"> + <ul> + <li class="post"><a href="/i/post"><i class="icon fa fa-pencil-square-o"></i>æ–°è¦æŠ•ç¨¿<i class="angle fa fa-angle-right"></i></a></li> + </ul> + <ul> + <li class="home"><a href="/"><i class="icon fa fa-home"></i>ホーム<i class="angle fa fa-angle-right"></i></a></li> + <li class="mentions"><a href="/i/mentions"><i class="icon fa fa-at"></i>ã‚ãªãŸå®›ã¦<i class="angle fa fa-angle-right"></i></a></li> + <li class="notifications"><a href="/i/notifications"><i class="icon fa fa-bell-o"></i>通知<i class="angle fa fa-angle-right"></i></a></li> + <li class="messaging"><a><i class="icon fa fa-comments-o"></i>メッセージ<i class="angle fa fa-angle-right"></i></a></li> + </ul> + <ul> + <li class="settings"><a onclick="{ search }"><i class="icon fa fa-search"></i>検索<i class="angle fa fa-angle-right"></i></a></li> + </ul> + <ul> + <li class="settings"><a href="/i/drive"><i class="icon fa fa-cloud"></i>ドライブ<i class="angle fa fa-angle-right"></i></a></li> + <li class="settings"><a href="/i/upload"><i class="icon fa fa-upload"></i>アップãƒãƒ¼ãƒ‰<i class="angle fa fa-angle-right"></i></a></li> + </ul> + <ul> + <li class="settings"><a href="/i/settings"><i class="icon fa fa-cog"></i>è¨å®š<i class="angle fa fa-angle-right"></i></a></li> + </ul> + </div> + <p class="about"><a>Misskeyã«ã¤ã„ã¦</a></p> + </div> + </div> + <style type="stylus"> + :scope display block - margin 0 16px - position absolute + position fixed top 0 - left 80px - padding 0 - width calc(100% - 112px) + left 0 + z-index -1 + width 240px color #fff - line-height 96px - overflow hidden - text-overflow ellipsis - white-space nowrap + background #313538 + visibility hidden - ul - display block - margin 16px 0 - padding 0 - list-style none + .body + height 100% + overflow hidden - &:first-child - margin-top 0 + .content + min-height 100% - li - display block - font-size 1em - line-height 1em - border-top solid 1px rgba(0, 0, 0, 0.2) - background #353A3E - background-clip content-box - - &:last-child - border-bottom solid 1px rgba(0, 0, 0, 0.2) - - a + .me display block - padding 0 20px - line-height 3rem - line-height calc(1rem + 30px) - color #eee - text-decoration none - - > .icon - margin-right 0.5em - - > .angle + margin 0 + padding 16px + + .avatar + display inline + max-width 64px + border-radius 32px + vertical-align middle + + .name + display block + margin 0 16px position absolute top 0 - right 0 - padding 0 20px - font-size 1.2em - line-height calc(1rem + 30px) - color #ccc - - > .unread-count - position absolute - height calc(0.9em + 10px) - line-height calc(0.9em + 10px) - top 0 - bottom 0 - right 38px - margin auto 0 - padding 0px 8px - min-width 2em - font-size 0.9em - text-align center + left 80px + padding 0 + width calc(100% - 112px) color #fff - background rgba(255, 255, 255, 0.1) - border-radius 1em - - .about - margin 1em 1em 2em 1em - text-align center - font-size 0.6em - opacity 0.3 + line-height 96px + overflow hidden + text-overflow ellipsis + white-space nowrap - a - color #fff + ul + display block + margin 16px 0 + padding 0 + list-style none + + &:first-child + margin-top 0 + + li + display block + font-size 1em + line-height 1em + border-top solid 1px rgba(0, 0, 0, 0.2) + background #353A3E + background-clip content-box + + &:last-child + border-bottom solid 1px rgba(0, 0, 0, 0.2) + + a + display block + padding 0 20px + line-height 3rem + line-height calc(1rem + 30px) + color #eee + text-decoration none + + > .icon + margin-right 0.5em + + > .angle + position absolute + top 0 + right 0 + padding 0 20px + font-size 1.2em + line-height calc(1rem + 30px) + color #ccc + + > .unread-count + position absolute + height calc(0.9em + 10px) + line-height calc(0.9em + 10px) + top 0 + bottom 0 + right 38px + margin auto 0 + padding 0px 8px + min-width 2em + font-size 0.9em + text-align center + color #fff + background rgba(255, 255, 255, 0.1) + border-radius 1em + + .about + margin 1em 1em 2em 1em + text-align center + font-size 0.6em + opacity 0.3 + + a + color #fff -script. - @mixin \i - @mixin \page + </style> + <script> + @mixin \i + @mixin \page - @on \mount ~> - @opts.ready! + @on \mount ~> + @opts.ready! - @search = ~> - query = window.prompt \検索 - if query? and query != '' - @page '/search:' + query + @search = ~> + query = window.prompt \検索 + if query? and query != '' + @page '/search:' + query + </script> +</mk-ui-nav> diff --git a/src/web/app/mobile/tags/ui.tag b/src/web/app/mobile/tags/ui.tag index 81dfac80ca4f656a7bc9c1286ad96add34db6b3f..966cfb4255cdfacf3ea7e2e1cb67a433aeae7417 100644 --- a/src/web/app/mobile/tags/ui.tag +++ b/src/web/app/mobile/tags/ui.tag @@ -1,50 +1,51 @@ -mk-ui - div.global@global - mk-ui-header@header(ready={ ready }) - mk-ui-nav@nav(ready={ ready }) - - div.content@main - <yield /> - - mk-stream-indicator - -style. - display block - - > .global - > .content - background #fff - -script. - @mixin \stream - - @ready-count = 0 - - #@ui.on \notification (text) ~> - # alert text - - @on \mount ~> - @stream.on \notification @on-stream-notification - @ready! - - @on \unmount ~> - @stream.off \notification @on-stream-notification - @slide.slide-close! - - @ready = ~> - @ready-count++ - - if @ready-count == 2 - @slide = SpSlidemenu @refs.main, @refs.nav.root, \#hamburger {direction: \left} - @init-view-position! - - @init-view-position = ~> - top = @refs.header.root.offset-height - @refs.main.style.padding-top = top + \px - @refs.nav.root.style.margin-top = top + \px - @refs.nav.root.query-selector '.body > .content' .style.padding-bottom = top + \px - - @on-stream-notification = (notification) ~> - el = document.body.append-child document.create-element \mk-notify - riot.mount el, do - notification: notification +<mk-ui> + <div class="global" ref="global"> + <mk-ui-header ref="header" ready="{ ready }"></mk-ui-header> + <mk-ui-nav ref="nav" ready="{ ready }"></mk-ui-nav> + <div class="content" ref="main"><yield /></div> + </div> + <mk-stream-indicator></mk-stream-indicator> + <style type="stylus"> + :scope + display block + + > .global + > .content + background #fff + + </style> + <script> + @mixin \stream + + @ready-count = 0 + + #@ui.on \notification (text) ~> + # alert text + + @on \mount ~> + @stream.on \notification @on-stream-notification + @ready! + + @on \unmount ~> + @stream.off \notification @on-stream-notification + @slide.slide-close! + + @ready = ~> + @ready-count++ + + if @ready-count == 2 + @slide = SpSlidemenu @refs.main, @refs.nav.root, \#hamburger {direction: \left} + @init-view-position! + + @init-view-position = ~> + top = @refs.header.root.offset-height + @refs.main.style.padding-top = top + \px + @refs.nav.root.style.margin-top = top + \px + @refs.nav.root.query-selector '.body > .content' .style.padding-bottom = top + \px + + @on-stream-notification = (notification) ~> + el = document.body.append-child document.create-element \mk-notify + riot.mount el, do + notification: notification + </script> +</mk-ui> diff --git a/src/web/app/mobile/tags/user-followers.tag b/src/web/app/mobile/tags/user-followers.tag index 7004398268abcbebb305bebcaf6d477448629558..00d11f3970d4aa6f4a4bf5d9e00221d6fda26125 100644 --- a/src/web/app/mobile/tags/user-followers.tag +++ b/src/web/app/mobile/tags/user-followers.tag @@ -1,22 +1,25 @@ -mk-user-followers - mk-users-list@list(fetch={ fetch }, count={ user.followers_count }, you-know-count={ user.followers_you_know_count }, no-users={ 'フォãƒãƒ¯ãƒ¼ã¯ã„ãªã„よã†ã§ã™ã€‚' }) +<mk-user-followers> + <mk-users-list ref="list" fetch="{ fetch }" count="{ user.followers_count }" you-know-count="{ user.followers_you_know_count }" no-users="{ 'フォãƒãƒ¯ãƒ¼ã¯ã„ãªã„よã†ã§ã™ã€‚' }"></mk-users-list> + <style type="stylus"> + :scope + display block -style. - display block + </style> + <script> + @mixin \api -script. - @mixin \api + @user = @opts.user - @user = @opts.user + @fetch = (iknow, limit, cursor, cb) ~> + @api \users/followers do + user_id: @user.id + iknow: iknow + limit: limit + cursor: if cursor? then cursor else undefined + .then cb - @fetch = (iknow, limit, cursor, cb) ~> - @api \users/followers do - user_id: @user.id - iknow: iknow - limit: limit - cursor: if cursor? then cursor else undefined - .then cb - - @on \mount ~> - @refs.list.on \loaded ~> - @trigger \loaded + @on \mount ~> + @refs.list.on \loaded ~> + @trigger \loaded + </script> +</mk-user-followers> diff --git a/src/web/app/mobile/tags/user-following.tag b/src/web/app/mobile/tags/user-following.tag index c122acd607735d98863595020bb821aa74ffe1d1..bbfa547c79f7c29d1ef2c12678e4e37f2b268019 100644 --- a/src/web/app/mobile/tags/user-following.tag +++ b/src/web/app/mobile/tags/user-following.tag @@ -1,22 +1,25 @@ -mk-user-following - mk-users-list@list(fetch={ fetch }, count={ user.following_count }, you-know-count={ user.following_you_know_count }, no-users={ 'フォãƒãƒ¼ä¸ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã„ãªã„よã†ã§ã™ã€‚' }) +<mk-user-following> + <mk-users-list ref="list" fetch="{ fetch }" count="{ user.following_count }" you-know-count="{ user.following_you_know_count }" no-users="{ 'フォãƒãƒ¼ä¸ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã„ãªã„よã†ã§ã™ã€‚' }"></mk-users-list> + <style type="stylus"> + :scope + display block -style. - display block + </style> + <script> + @mixin \api -script. - @mixin \api + @user = @opts.user - @user = @opts.user + @fetch = (iknow, limit, cursor, cb) ~> + @api \users/following do + user_id: @user.id + iknow: iknow + limit: limit + cursor: if cursor? then cursor else undefined + .then cb - @fetch = (iknow, limit, cursor, cb) ~> - @api \users/following do - user_id: @user.id - iknow: iknow - limit: limit - cursor: if cursor? then cursor else undefined - .then cb - - @on \mount ~> - @refs.list.on \loaded ~> - @trigger \loaded + @on \mount ~> + @refs.list.on \loaded ~> + @trigger \loaded + </script> +</mk-user-following> diff --git a/src/web/app/mobile/tags/user-preview.tag b/src/web/app/mobile/tags/user-preview.tag index 56bd93825c8e4ca9585f4f8245ef9f98b46f4ce7..7b00043a1cfeff63e9e18cade2b3eb2438915cec 100644 --- a/src/web/app/mobile/tags/user-preview.tag +++ b/src/web/app/mobile/tags/user-preview.tag @@ -1,92 +1,89 @@ -mk-user-preview - a.avatar-anchor(href={ CONFIG.url + '/' + user.username }) - img.avatar(src={ user.avatar_url + '?thumbnail&size=64' }, alt='avatar') - div.main - header - a.name(href={ CONFIG.url + '/' + user.username }) - | { user.name } - span.username - | @{ user.username } - div.body - div.bio { user.bio } - -style. - display block - margin 0 - padding 16px - font-size 12px - - @media (min-width 350px) - font-size 14px - - @media (min-width 500px) - font-size 16px - - &:after - content "" - display block - clear both - - > .avatar-anchor - display block - float left - margin 0 10px 0 0 - - @media (min-width 500px) - margin-right 16px - - > .avatar +<mk-user-preview><a class="avatar-anchor" href="{ CONFIG.url + '/' + user.username }"><img class="avatar" src="{ user.avatar_url + '?thumbnail&size=64' }" alt="avatar"/></a> + <div class="main"> + <header><a class="name" href="{ CONFIG.url + '/' + user.username }">{ user.name }</a><span class="username">@{ user.username }</span></header> + <div class="body"> + <div class="bio">{ user.bio }</div> + </div> + </div> + <style type="stylus"> + :scope display block - width 48px - height 48px margin 0 - border-radius 6px - vertical-align bottom + padding 16px + font-size 12px - @media (min-width 500px) - width 58px - height 58px - border-radius 8px + @media (min-width 350px) + font-size 14px - > .main - float left - width calc(100% - 58px) + @media (min-width 500px) + font-size 16px - @media (min-width 500px) - width calc(100% - 74px) + &:after + content "" + display block + clear both - > header - @media (min-width 500px) - margin-bottom 2px - - > .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 - - > .bio - cursor default + > .avatar-anchor display block - margin 0 - padding 0 - word-wrap break-word - font-size 1.1em - color #717171 - -script. - @user = @opts.user + float left + margin 0 10px 0 0 + + @media (min-width 500px) + margin-right 16px + + > .avatar + display block + width 48px + height 48px + margin 0 + border-radius 6px + vertical-align bottom + + @media (min-width 500px) + width 58px + height 58px + border-radius 8px + + > .main + float left + width calc(100% - 58px) + + @media (min-width 500px) + width calc(100% - 74px) + + > header + @media (min-width 500px) + margin-bottom 2px + + > .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 + + > .bio + cursor default + display block + margin 0 + padding 0 + word-wrap break-word + font-size 1.1em + color #717171 + + </style> + <script>@user = @opts.user</script> +</mk-user-preview> diff --git a/src/web/app/mobile/tags/user-timeline.tag b/src/web/app/mobile/tags/user-timeline.tag index 848405d24eaacda9dbc010fd353bc7149474d282..354c0790c2b9c165d4ed39d589f5a2d0e7e77d2c 100644 --- a/src/web/app/mobile/tags/user-timeline.tag +++ b/src/web/app/mobile/tags/user-timeline.tag @@ -1,28 +1,31 @@ -mk-user-timeline - mk-timeline@timeline(init={ init }, more={ more }, empty={ with-media ? 'メディア付ã投稿ã¯ã‚ã‚Šã¾ã›ã‚“。' : 'ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã¾ã 投稿ã—ã¦ã„ãªã„よã†ã§ã™ã€‚' }) +<mk-user-timeline> + <mk-timeline ref="timeline" init="{ init }" more="{ more }" empty="{ withMedia ? 'メディア付ã投稿ã¯ã‚ã‚Šã¾ã›ã‚“。' : 'ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ã¾ã 投稿ã—ã¦ã„ãªã„よã†ã§ã™ã€‚' }"></mk-timeline> + <style type="stylus"> + :scope + display block + max-width 600px + margin 0 auto + background #fff -style. - display block - max-width 600px - margin 0 auto - background #fff + </style> + <script> + @mixin \api -script. - @mixin \api + @user = @opts.user + @with-media = @opts.with-media - @user = @opts.user - @with-media = @opts.with-media + @init = new Promise (res, rej) ~> + @api \users/posts do + user_id: @user.id + with_media: @with-media + .then (posts) ~> + res posts + @trigger \loaded - @init = new Promise (res, rej) ~> - @api \users/posts do - user_id: @user.id - with_media: @with-media - .then (posts) ~> - res posts - @trigger \loaded - - @more = ~> - @api \users/posts do - user_id: @user.id - with_media: @with-media - max_id: @refs.timeline.tail!.id + @more = ~> + @api \users/posts do + user_id: @user.id + with_media: @with-media + max_id: @refs.timeline.tail!.id + </script> +</mk-user-timeline> diff --git a/src/web/app/mobile/tags/user.tag b/src/web/app/mobile/tags/user.tag index 1ecbc3d99ee3b3eb0da31560a15d46fdc19a0d7b..bce6c883f5f6036ddd90ab9a1033c26f5cc68e8b 100644 --- a/src/web/app/mobile/tags/user.tag +++ b/src/web/app/mobile/tags/user.tag @@ -1,201 +1,189 @@ -mk-user - div.user(if={ !fetching }) - header - div.banner(style={ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=1024)' : '' }) - div.body - div.top - a.avatar: img(src={ user.avatar_url + '?thumbnail&size=160' }, alt='avatar') - mk-follow-button(if={ SIGNIN && I.id != user.id }, user={ user }) - - div.title - h1 { user.name } - span.username @{ user.username } - span.followed(if={ user.is_followed }) フォãƒãƒ¼ã•ã‚Œã¦ã„ã¾ã™ - - div.bio { user.bio } - - div.info - p.location(if={ user.location }) - i.fa.fa-map-marker - | { user.location } - p.birthday(if={ user.birthday }) - i.fa.fa-birthday-cake - | { user.birthday.replace('-', 'å¹´').replace('-', '月') + 'æ—¥' } - - div.friends - a(href='{ user.username }/following') - b { user.following_count } - i フォãƒãƒ¼ - a(href='{ user.username }/followers') - b { user.followers_count } - i フォãƒãƒ¯ãƒ¼ - nav - a(data-is-active={ page == 'posts' }, onclick={ go-posts }) 投稿 - a(data-is-active={ page == 'media' }, onclick={ go-media }) メディア - a(data-is-active={ page == 'graphs' }, onclick={ go-graphs }) グラフ - a(data-is-active={ page == 'likes' }, onclick={ go-likes }) ã„ã„ã - - div.body - mk-user-timeline(if={ page == 'posts' }, user={ user }) - mk-user-timeline(if={ page == 'media' }, user={ user }, with-media={ true }) - mk-user-graphs(if={ page == 'graphs' }, user={ user }) - -style. - display block - - > .user - > header - > .banner - padding-bottom 33.3% - background-color #f5f5f5 - background-size cover - background-position center - - > .body - padding 8px - margin 0 auto - max-width 600px - - > .top - &:after - content '' - display block - clear both - - > .avatar - display block - float left - width 25% - height 40px - - > img +<mk-user> + <div class="user" if="{ !fetching }"> + <header> + <div class="banner" style="{ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=1024)' : '' }"></div> + <div class="body"> + <div class="top"><a class="avatar"><img src="{ user.avatar_url + '?thumbnail&size=160' }" alt="avatar"/></a> + <mk-follow-button if="{ SIGNIN && I.id != user.id }" user="{ user }"></mk-follow-button> + </div> + <div class="title"> + <h1>{ user.name }</h1><span class="username">@{ user.username }</span><span class="followed" if="{ user.is_followed }">フォãƒãƒ¼ã•ã‚Œã¦ã„ã¾ã™</span> + </div> + <div class="bio">{ user.bio }</div> + <div class="info"> + <p class="location" if="{ user.location }"><i class="fa fa-map-marker"></i>{ user.location }</p> + <p class="birthday" if="{ user.birthday }"><i class="fa fa-birthday-cake"></i>{ user.birthday.replace('-', 'å¹´').replace('-', '月') + 'æ—¥' }</p> + </div> + <div class="friends"><a href="{ user.username }/following"><b>{ user.following_count }</b><i>フォãƒãƒ¼</i></a><a href="{ user.username }/followers"><b>{ user.followers_count }</b><i>フォãƒãƒ¯ãƒ¼</i></a></div> + </div> + <nav><a data-is-active="{ page == 'posts' }" onclick="{ goPosts }">投稿</a><a data-is-active="{ page == 'media' }" onclick="{ goMedia }">メディア</a><a data-is-active="{ page == 'graphs' }" onclick="{ goGraphs }">グラフ</a><a data-is-active="{ page == 'likes' }" onclick="{ goLikes }">ã„ã„ã</a></nav> + </header> + <div class="body"> + <mk-user-timeline if="{ page == 'posts' }" user="{ user }"></mk-user-timeline> + <mk-user-timeline if="{ page == 'media' }" user="{ user }" with-media="{ true }"></mk-user-timeline> + <mk-user-graphs if="{ page == 'graphs' }" user="{ user }"></mk-user-graphs> + </div> + </div> + <style type="stylus"> + :scope + display block + + > .user + > header + > .banner + padding-bottom 33.3% + background-color #f5f5f5 + background-size cover + background-position center + + > .body + padding 8px + margin 0 auto + max-width 600px + + > .top + &:after + content '' + display block + clear both + + > .avatar + display block + float left + width 25% + height 40px + + > img + display block + position absolute + left -2px + bottom -2px + width 100% + border 2px solid #fff + border-radius 6px + + @media (min-width 500px) + left -4px + bottom -4px + border 4px solid #fff + border-radius 12px + + > mk-follow-button + float right + height 40px + + > .title + margin 8px 0 + + > h1 + margin 0 + line-height 22px + font-size 20px + color #222 + + > .username + display inline-block + line-height 20px + font-size 16px + font-weight bold + color #657786 + + > .followed + margin-left 8px + padding 2px 4px + font-size 12px + color #657786 + background #f8f8f8 + border-radius 4px + + > .bio + margin 8px 0 + color #333 + + > .info + margin 8px 0 + + > p + display inline + margin 0 16px 0 0 + color #555 + + > i + margin-right 4px + + > .friends + > a + color #657786 + + &:first-child + margin-right 16px + + > b + margin-right 4px + font-size 16px + color #14171a + + > i + font-size 14px + + > nav + display flex + justify-content center + margin 0 auto + max-width 600px + border-bottom solid 1px #ddd + + > a display block - position absolute - left -2px - bottom -2px - width 100% - border 2px solid #fff - border-radius 6px - - @media (min-width 500px) - left -4px - bottom -4px - border 4px solid #fff - border-radius 12px - - > mk-follow-button - float right - height 40px - - > .title - margin 8px 0 - - > h1 - margin 0 - line-height 22px - font-size 20px - color #222 - - > .username - display inline-block - line-height 20px - font-size 16px - font-weight bold - color #657786 - - > .followed - margin-left 8px - padding 2px 4px - font-size 12px - color #657786 - background #f8f8f8 - border-radius 4px - - > .bio - margin 8px 0 - color #333 - - > .info - margin 8px 0 - - > p - display inline - margin 0 16px 0 0 - color #555 - - > i - margin-right 4px - - > .friends - > a - color #657786 - - &:first-child - margin-right 16px - - > b - margin-right 4px - font-size 16px - color #14171a - - > i + flex 1 1 + text-align center + line-height 52px font-size 14px - - > nav - display flex - justify-content center - margin 0 auto - max-width 600px - border-bottom solid 1px #ddd - - > a - display block - flex 1 1 - text-align center - line-height 52px - font-size 14px - text-decoration none - color #657786 - border-bottom solid 2px transparent - - &[data-is-active] - font-weight bold - color $theme-color - border-color $theme-color - - > .body - @media (min-width 500px) - padding 16px 0 0 0 - -script. - @mixin \i - @mixin \api - - @username = @opts.user - @page = if @opts.page? then @opts.page else \posts - @fetching = true - - @on \mount ~> - @api \users/show do - username: @username - .then (user) ~> - @fetching = false - @user = user - @trigger \loaded user + text-decoration none + color #657786 + border-bottom solid 2px transparent + + &[data-is-active] + font-weight bold + color $theme-color + border-color $theme-color + + > .body + @media (min-width 500px) + padding 16px 0 0 0 + + </style> + <script> + @mixin \i + @mixin \api + + @username = @opts.user + @page = if @opts.page? then @opts.page else \posts + @fetching = true + + @on \mount ~> + @api \users/show do + username: @username + .then (user) ~> + @fetching = false + @user = user + @trigger \loaded user + @update! + + @go-posts = ~> + @page = \posts @update! - @go-posts = ~> - @page = \posts - @update! - - @go-media = ~> - @page = \media - @update! + @go-media = ~> + @page = \media + @update! - @go-graphs = ~> - @page = \graphs - @update! + @go-graphs = ~> + @page = \graphs + @update! - @go-likes = ~> - @page = \likes - @update! + @go-likes = ~> + @page = \likes + @update! + </script> +</mk-user> diff --git a/src/web/app/mobile/tags/users-list.tag b/src/web/app/mobile/tags/users-list.tag index 3e29a0a4ccd3edfd2df4b154d07c3c6af7fd6d40..f64f196e46b058c7fc07e503ca790533caea5d16 100644 --- a/src/web/app/mobile/tags/users-list.tag +++ b/src/web/app/mobile/tags/users-list.tag @@ -1,125 +1,116 @@ -mk-users-list - nav - span(data-is-active={ mode == 'all' }, onclick={ set-mode.bind(this, 'all') }) - | ã™ã¹ã¦ - span { opts.count } - // ↓ https://github.com/riot/riot/issues/2080 - span(if={ SIGNIN && opts.you-know-count != '' }, data-is-active={ mode == 'iknow' }, onclick={ set-mode.bind(this, 'iknow') }) - | 知りåˆã„ - span { opts.you-know-count } - - div.users(if={ !fetching && users.length != 0 }) - mk-user-preview(each={ users }, user={ this }) - - button.more(if={ !fetching && next != null }, onclick={ more }, disabled={ more-fetching }) - span(if={ !more-fetching }) ã‚‚ã£ã¨ - span(if={ more-fetching }) - | èªã¿è¾¼ã¿ä¸ - mk-ellipsis - - p.no(if={ !fetching && users.length == 0 }) - | { opts.no-users } - p.fetching(if={ fetching }) - i.fa.fa-spinner.fa-pulse.fa-fw - | èªã¿è¾¼ã‚“ã§ã„ã¾ã™ - mk-ellipsis - -style. - display block - background #fff - - > nav - display flex - justify-content center - margin 0 auto - max-width 600px - border-bottom solid 1px #ddd - - > span +<mk-users-list> + <nav><span data-is-active="{ mode == 'all' }" onclick="{ setMode.bind(this, 'all') }">ã™ã¹ã¦<span>{ opts.count }</span></span> + <!-- ↓ https://github.com/riot/riot/issues/2080--><span if="{ SIGNIN && opts.youKnowCount != '' }" data-is-active="{ mode == 'iknow' }" onclick="{ setMode.bind(this, 'iknow') }">知りåˆã„<span>{ opts.youKnowCount }</span></span> + </nav> + <div class="users" if="{ !fetching && users.length != 0 }"> + <mk-user-preview each="{ users }" user="{ this }"></mk-user-preview> + </div> + <button class="more" if="{ !fetching && next != null }" onclick="{ more }" disabled="{ moreFetching }"><span if="{ !moreFetching }">ã‚‚ã£ã¨</span><span if="{ moreFetching }">èªã¿è¾¼ã¿ä¸ + <mk-ellipsis></mk-ellipsis></span></button> + <p class="no" if="{ !fetching && users.length == 0 }">{ opts.noUsers }</p> + <p class="fetching" if="{ fetching }"><i class="fa fa-spinner fa-pulse fa-fw"></i>èªã¿è¾¼ã‚“ã§ã„ã¾ã™ + <mk-ellipsis></mk-ellipsis> + </p> + <style type="stylus"> + :scope display block - flex 1 1 - text-align center - line-height 52px - font-size 14px - color #657786 - border-bottom solid 2px transparent - - &[data-is-active] - font-weight bold - color $theme-color - border-color $theme-color - - > span - display inline-block - margin-left 4px - padding 2px 5px - font-size 12px - line-height 1 - color #888 - background #eee - border-radius 20px - - > .users - > * - max-width 600px - margin 0 auto - border-bottom solid 1px rgba(0, 0, 0, 0.05) - - > .no - margin 0 - padding 16px - text-align center - color #aaa - - > .fetching - margin 0 - padding 16px - text-align center - color #aaa - - > i - margin-right 4px - -script. - @mixin \i - - @limit = 30users - @mode = \all - - @fetching = true - @more-fetching = false - - @on \mount ~> - @fetch ~> - @trigger \loaded - - @fetch = (cb) ~> + background #fff + + > nav + display flex + justify-content center + margin 0 auto + max-width 600px + border-bottom solid 1px #ddd + + > span + display block + flex 1 1 + text-align center + line-height 52px + font-size 14px + color #657786 + border-bottom solid 2px transparent + + &[data-is-active] + font-weight bold + color $theme-color + border-color $theme-color + + > span + display inline-block + margin-left 4px + padding 2px 5px + font-size 12px + line-height 1 + color #888 + background #eee + border-radius 20px + + > .users + > * + max-width 600px + margin 0 auto + border-bottom solid 1px rgba(0, 0, 0, 0.05) + + > .no + margin 0 + padding 16px + text-align center + color #aaa + + > .fetching + margin 0 + padding 16px + text-align center + color #aaa + + > i + margin-right 4px + + </style> + <script> + @mixin \i + + @limit = 30users + @mode = \all + @fetching = true - @update! - obj <~ @opts.fetch do - @mode == \iknow - @limit - null - @users = obj.users - @next = obj.next - @fetching = false - @update! - if cb? then cb! - - @more = ~> - @more-fetching = true - @update! - obj <~ @opts.fetch do - @mode == \iknow - @limit - @cursor - @users = @users.concat obj.users - @next = obj.next @more-fetching = false - @update! - - @set-mode = (mode) ~> - @update do - mode: mode - @fetch! + @on \mount ~> + @fetch ~> + @trigger \loaded + + @fetch = (cb) ~> + @fetching = true + @update! + obj <~ @opts.fetch do + @mode == \iknow + @limit + null + @users = obj.users + @next = obj.next + @fetching = false + @update! + if cb? then cb! + + @more = ~> + @more-fetching = true + @update! + obj <~ @opts.fetch do + @mode == \iknow + @limit + @cursor + @users = @users.concat obj.users + @next = obj.next + @more-fetching = false + @update! + + @set-mode = (mode) ~> + @update do + mode: mode + + @fetch! + </script> +</mk-users-list>