This commit is contained in:
syuilo 2017-02-21 11:44:53 +09:00
parent 7921d3508a
commit 3ea73a888d
12 changed files with 334 additions and 256 deletions

View file

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

View file

@ -71,54 +71,70 @@
this.mixin('is-promise'); this.mixin('is-promise');
this.mixin('stream'); this.mixin('stream');
this.user = null this.user = null;
this.user-promise = if @is-promise this.opts.user then this.opts.user else Promise.resolve this.opts.user this.userPromise = this.isPromise(this.opts.user)
this.init = true ? this.opts.user
this.wait = false : Promise.resolve(this.opts.user);
this.init = true;
this.wait = false;
this.on('mount', () => { this.on('mount', () => {
this.user-promise}).then((user) => { this.userPromise.then(user => {
this.user = user this.update({
this.init = false init: false,
this.update(); user: user
this.stream.on 'follow' this.on-stream-follow });
this.stream.on 'unfollow' this.on-stream-unfollow this.stream.on('follow', this.onStreamFollow);
this.stream.on('unfollow', this.onStreamUnfollow);
});
});
this.on('unmount', () => { this.on('unmount', () => {
this.stream.off 'follow' this.on-stream-follow this.stream.off('follow', this.onStreamFollow);
this.stream.off 'unfollow' this.on-stream-unfollow this.stream.off('unfollow', this.onStreamUnfollow);
});
this.on-stream-follow = (user) => { this.onStreamFollow = user => {
if user.id == this.user.id if (user.id == this.user.id) {
this.user = user this.update({
this.update(); user: user
});
}
};
this.on-stream-unfollow = (user) => { this.onStreamUnfollow = user => {
if user.id == this.user.id if (user.id == this.user.id) {
this.user = user this.update({
this.update(); user: user
});
}
};
this.onclick = () => { this.onclick = () => {
this.wait = true this.wait = true;
if this.user.is_following if (this.user.is_following) {
this.api('following/delete', { this.api('following/delete', {
user_id: this.user.id user_id: this.user.id
}).then(() => { }).then(() => {
this.user.is_following = false this.user.is_following = false;
.catch (err) -> }).catch(err => {
console.error err console.error(err);
}).then(() => { }).then(() => {
this.wait = false this.wait = false;
this.update(); this.update();
else });
} else {
this.api('following/create', { this.api('following/create', {
user_id: this.user.id user_id: this.user.id
}).then(() => { }).then(() => {
this.user.is_following = true this.user.is_following = true;
.catch (err) -> }).catch(err => {
console.error err console.error(err);
}).then(() => { }).then(() => {
this.wait = false this.wait = false;
this.update(); this.update();
});
}
};
</script> </script>
</mk-follow-button> </mk-follow-button>

View file

@ -59,32 +59,39 @@
</style> </style>
<script> <script>
this.mixin('i'); this.mixin('i');
this.mode = this.opts.mode || 'timeline'
this.mode = this.opts.mode || 'timeline';
// https://github.com/riot/riot/issues/2080 // https://github.com/riot/riot/issues/2080
if this.mode == '' then this.mode = 'timeline' if (this.mode == '') this.mode = 'timeline';
this.home = [] this.home = [];
this.on('mount', () => { this.on('mount', () => {
this.refs.tl.on('loaded', () => { this.refs.tl.on('loaded', () => {
this.trigger('loaded'); this.trigger('loaded');
});
this.I.data.home.forEach (widget) => this.I.data.home.forEach(widget => {
try try {
el = document.createElement 'mk-' + widget.name + '-home-widget' const el = document.createElement(`mk-${widget.name}-home-widget`);
switch widget.place switch (widget.place) {
| 'left' => this.refs.left.appendChild el case 'left': this.refs.left.appendChild(el); break;
| 'right' => this.refs.right.appendChild el case 'right': this.refs.right.appendChild(el); break;
@home.push (riot.mount el, do }
id: widget.id this.home.push(riot.mount(el, {
id: widget.id,
data: widget.data data: widget.data
.0) })[0]);
catch e } catch (e) {
// noop // noop
}
});
});
this.on('unmount', () => { this.on('unmount', () => {
@home.forEach (widget) => this.home.forEach(widget => {
widget.unmount! widget.unmount();
});
});
</script> </script>
</mk-home> </mk-home>

View file

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

View file

@ -35,11 +35,13 @@
this.mixin('update-avatar'); this.mixin('update-avatar');
this.set = () => { this.set = () => {
@update-avatar this.I this.updateAvatar(this.I);
};
this.close = (e) => { this.close = e => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
this.unmount(); this.unmount();
};
</script> </script>
</mk-set-avatar-suggestion> </mk-set-avatar-suggestion>

View file

@ -35,11 +35,13 @@
this.mixin('update-banner'); this.mixin('update-banner');
this.set = () => { this.set = () => {
@update-banner this.I this.updateBanner(this.I);
};
this.close = (e) => { this.close = e => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
this.unmount(); this.unmount();
};
</script> </script>
</mk-set-banner-suggestion> </mk-set-banner-suggestion>

View file

@ -3,7 +3,9 @@
<mk-timeline-post post={ post }></mk-timeline-post> <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> <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> </virtual>
<footer data-yield="footer"><yield from="footer"/></footer> <footer data-yield="footer">
<yield from="footer"/>
</footer>
<style> <style>
:scope :scope
display block display block
@ -44,36 +46,47 @@
</style> </style>
<script> <script>
this.posts = [] this.posts = [];
this.set-posts = (posts) => {
this.posts = posts
this.update();
this.prepend-posts = (posts) => {
posts.forEach (post) =>
this.posts.push post
this.update();
this.add-post = (post) => {
this.posts.unshift post
this.update();
this.clear = () => {
this.posts = []
this.update();
this.focus = () => {
this.root.children.0.focus();
this.on('update', () => { this.on('update', () => {
this.posts.forEach (post) => this.posts.forEach(post => {
date = (new Date post.created_at).getDate() const date = new Date(post.created_at).getDate();
month = (new Date post.created_at).getMonth() + 1 const month = new Date(post.created_at).getMonth() + 1;
post._date = date post._date = date;
post._datetext = month + '月 ' + date + '日' post._datetext = `${month}月 ${date}日`;
});
});
this.setPosts = posts => {
this.update({
posts: posts
});
};
this.prependPosts = posts => {
posts.forEach(post => {
this.posts.push(post);
this.update();
});
}
this.addPost = post => {
this.posts.unshift(post);
this.update();
};
this.tail = () => { this.tail = () => {
this.posts[this.posts.length - 1] return this.posts[this.posts.length - 1];
};
this.clear = () => {
this.posts = [];
this.update();
};
this.focus = () => {
this.root.children[0].focus();
};
</script> </script>
</mk-timeline> </mk-timeline>

View file

@ -50,89 +50,84 @@
this.mixin('is-promise'); this.mixin('is-promise');
this.mixin('get-post-summary'); this.mixin('get-post-summary');
this.user = null this.user = null;
this.user-promise = if @is-promise this.opts.user then this.opts.user else Promise.resolve this.opts.user this.userPromise = this.isPromise(this.opts.user)
this.is-loading = true ? this.opts.user
this.is-empty = false : Promise.resolve(this.opts.user);
this.more-loading = false this.isLoading = true;
this.unread-count = 0 this.isEmpty = false;
this.mode = 'default' this.moreLoading = false;
this.unreadCount = 0;
this.mode = 'default';
this.on('mount', () => { this.on('mount', () => {
document.addEventListener 'visibilitychange' @window-onVisibilitychange, false document.addEventListener('keydown', this.onDocumentKeydown);
document.addEventListener 'keydown' this.on-document-keydown window.addEventListener('scroll', this.onScroll);
window.addEventListener 'scroll' this.on-scroll
this.user-promise}).then((user) => { this.userPromise.then(user => {
this.user = user this.update({
this.update(); user: user
});
@fetch => this.fetch(() => this.trigger('loaded'));
this.trigger('loaded'); });
this.on('unmount', () => { this.on('unmount', () => {
document.removeEventListener 'visibilitychange' @window-onVisibilitychange document.removeEventListener('keydown', this.onDocumentKeydown);
document.removeEventListener 'keydown' this.on-document-keydown window.removeEventListener('scroll', this.onScroll);
window.removeEventListener 'scroll' this.on-scroll });
this.on-document-keydown = (e) => { this.onDocumentKeydown = e => {
tag = e.target.tag-name.to-lower-case! if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') {
if tag != 'input' and tag != 'textarea' if (e.which == 84) { // [t]
if e.which == 84 // t
this.refs.timeline.focus(); this.refs.timeline.focus();
}
}
};
this.fetch = (cb) => { this.fetch = cb => {
this.api('users/posts', { this.api('users/posts', {
user_id: this.user.id user_id: this.user.id,
with_replies: this.mode == 'with-replies' with_replies: this.mode == 'with-replies'
}).then((posts) => { }).then(posts => {
this.is-loading = false this.update({
this.is-empty = posts.length == 0 isLoading: false,
this.update(); isEmpty: posts.length == 0
this.refs.timeline.set-posts posts });
if cb? then cb! this.refs.timeline.setPosts(posts);
.catch (err) => if (cb) cb();
console.error err });
if cb? then cb! };
this.more = () => { this.more = () => {
if @more-loading or @is-loading or this.refs.timeline.posts.length == 0 if (this.moreLoading || this.isLoading || this.refs.timeline.posts.length == 0) return;
return this.update({
this.more-loading = true moreLoading: true
this.update(); });
this.api('users/posts', { this.api('users/posts', {
user_id: this.user.id user_id: this.user.id,
with_replies: this.mode == 'with-replies' with_replies: this.mode == 'with-replies',
max_id: this.refs.timeline.tail!.id max_id: this.refs.timeline.tail().id
}).then((posts) => { }).then(posts => {
this.more-loading = false this.update({
this.update(); moreLoading: false
this.refs.timeline.prepend-posts posts });
.catch (err) => this.refs.timeline.prependPosts(posts);
console.error err });
};
this.on-stream-post = (post) => { this.onScroll = () => {
this.is-empty = false const current = window.scrollY + window.innerHeight;
this.update(); if (current > document.body.offsetHeight - 16/*遊び*/) {
this.refs.timeline.add-post post this.more();
}
};
if document.hidden this.setMode = mode => {
@unread-count++ this.update({
document.title = '(' + @unread-count + ') ' + @get-post-summary post
this.window-onVisibilitychange = () => {
if !document.hidden
this.unread-count = 0
document.title = 'Misskey'
this.on-scroll = () => {
current = window.scrollY + window.inner-height
if current > document.body.offset-height - 16 // 遊び
@more!
this.set-mode = (mode) => {
@update do
mode: mode mode: mode
@fetch! });
this.fetch();
};
</script> </script>
</mk-user-timeline> </mk-user-timeline>

View file

@ -1,7 +1,9 @@
<mk-users-list> <mk-users-list>
<nav> <nav>
<div><span data-is-active={ mode == 'all' } onclick={ setMode.bind(this, 'all') }>すべて<span>{ opts.count }</span></span> <div>
<!-- ↓ 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> <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> </div>
</nav> </nav>
<div class="users" if={ !fetching && users.length != 0 }> <div class="users" if={ !fetching && users.length != 0 }>
@ -9,8 +11,10 @@
<mk-list-user user={ this }></mk-list-user> <mk-list-user user={ this }></mk-list-user>
</div> </div>
</div> </div>
<button class="more" if={ !fetching && next != null } onclick={ more } disabled={ moreFetching }><span if={ !moreFetching }>もっと</span><span if={ moreFetching }>読み込み中 <button class="more" if={ !fetching && next != null } onclick={ more } disabled={ moreFetching }>
<mk-ellipsis></mk-ellipsis></span></button> <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="no" if={ !fetching && users.length == 0 }>{ opts.noUsers }</p>
<p class="fetching" if={ fetching }><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます <p class="fetching" if={ fetching }><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます
<mk-ellipsis></mk-ellipsis> <mk-ellipsis></mk-ellipsis>
@ -90,45 +94,48 @@
<script> <script>
this.mixin('i'); this.mixin('i');
this.limit = 30users this.limit = 30;
this.mode = 'all' this.mode = 'all';
this.fetching = true this.fetching = true;
this.more-fetching = false this.moreFetching = false;
this.on('mount', () => { this.on('mount', () => {
@fetch => this.fetch(() => this.trigger('loaded'));
this.trigger('loaded'); });
this.fetch = (cb) => { this.fetch = cb => {
this.fetching = true this.update({
this.update(); fetching: true
obj <~ this.opts.fetch do });
this.mode == 'iknow' this.opts.fetch(this.mode == 'iknow', this.limit, null, obj => {
@limit this.update({
null fetching: false,
this.users = obj.users users: obj.users,
this.next = obj.next next: obj.next
this.fetching = false });
this.update(); if (cb) cb();
if cb? then cb! });
};
this.more = () => { this.more = () => {
this.more-fetching = true this.update({
this.update(); moreFetching: true
obj <~ this.opts.fetch do });
this.mode == 'iknow' this.opts.fetch(this.mode == 'iknow', this.limit, this.cursor, obj => {
@limit this.update({
@cursor moreFetching: false,
this.users = this.users.concat obj.users users: this.users.concat(obj.users),
this.next = obj.next next: obj.next
this.more-fetching = false });
this.update(); });
};
this.set-mode = (mode) => { this.setMode = mode => {
@update do this.update({
mode: mode mode: mode
});
@fetch! this.fetch();
};
</script> </script>
</mk-users-list> </mk-users-list>

View file

@ -3,41 +3,49 @@
<style> <style>
:scope :scope
display block display block
</style> </style>
<script> <script>
this.mixin('api'); this.mixin('api');
this.mixin('stream'); this.mixin('stream');
this.init = new Promise (res, rej) => this.init = new Promise((res, rej) => {
this.api 'posts/timeline' this.api('posts/timeline').then(posts => {
}).then((posts) => { res(posts);
res posts
this.trigger('loaded'); this.trigger('loaded');
});
});
this.on('mount', () => { this.on('mount', () => {
this.stream.on 'post' this.on-stream-post this.stream.on('post', this.onStreamPost);
this.stream.on 'follow' this.on-stream-follow this.stream.on('follow', this.onStreamFollow);
this.stream.on 'unfollow' this.on-stream-unfollow this.stream.on('unfollow', this.onStreamUnfollow);
});
this.on('unmount', () => { this.on('unmount', () => {
this.stream.off 'post' this.on-stream-post this.stream.off('post', this.onStreamPost);
this.stream.off 'follow' this.on-stream-follow this.stream.off('follow', this.onStreamFollow);
this.stream.off 'unfollow' this.on-stream-unfollow this.stream.off('unfollow', this.onStreamUnfollow);
});
this.more = () => { this.more = () => {
this.api('posts/timeline', { this.api('posts/timeline', {
max_id: this.refs.timeline.tail!.id max_id: this.refs.timeline.tail().id
});
};
this.on-stream-post = (post) => { this.onStreamPost = post => {
this.is-empty = false this.update({
this.update(); isEmpty: false
this.refs.timeline.add-post post });
this.refs.timeline.addPost(post);
};
this.on-stream-follow = () => { this.onStreamFollow = () => {
@fetch! this.fetch();
};
this.on-stream-unfollow = () => { this.onStreamUnfollow = () => {
@fetch! this.fetch();
};
</script> </script>
</mk-home-timeline> </mk-home-timeline>

View file

@ -74,45 +74,58 @@
</style> </style>
<script> <script>
this.posts = [] this.posts = [];
this.init = true this.init = true;
this.fetching = false this.fetching = false;
this.can-fetch-more = true this.canFetchMore = true;
this.on('mount', () => { this.on('mount', () => {
this.opts.init}).then((posts) => { this.opts.init.then(posts => {
this.init = false this.init = false;
@set-posts posts this.setPosts(posts);
});
});
this.on('update', () => { this.on('update', () => {
this.posts.forEach (post) => this.posts.forEach(post => {
date = (new Date post.created_at).getDate() const date = new Date(post.created_at).getDate();
month = (new Date post.created_at).getMonth() + 1 const month = new Date(post.created_at).getMonth() + 1;
post._date = date post._date = date;
post._datetext = month + '月 ' + date + '日' post._datetext = `${month}月 ${date}日`;
});
});
this.more = () => { this.more = () => {
if @init or @fetching or this.posts.length == 0 then return if (this.init || this.fetching || this.posts.length == 0) return;
this.fetching = true this.update({
this.update(); fetching: true
this.opts.more!}).then((posts) => { });
this.fetching = false this.opts.more().then(posts => {
this.prepend-posts posts this.fetching = false;
this.prependPosts(posts);
});
};
this.set-posts = (posts) => { this.setPosts = posts => {
this.posts = posts this.update({
this.update(); posts: posts
});
};
this.prepend-posts = (posts) => { this.prependPosts = posts => {
posts.forEach (post) => posts.forEach(post => {
this.posts.push post this.posts.push(post);
this.update(); this.update();
});
}
this.add-post = (post) => { this.addPost = post => {
this.posts.unshift post this.posts.unshift(post);
this.update(); this.update();
};
this.tail = () => { this.tail = () => {
this.posts[this.posts.length - 1] return this.posts[this.posts.length - 1];
};
</script> </script>
</mk-timeline> </mk-timeline>

View file

@ -89,16 +89,18 @@
</style> </style>
<script> <script>
this.mixin('ui'); this.mixin('ui');
this.mixin('openPostForm'); this.mixin('open-post-form');
this.on('mount', () => { this.on('mount', () => {
this.opts.ready! this.opts.ready();
});
this.ui.on('title', (title) => { this.ui.on('title', title => {
if this.refs.title? if (this.refs.title) this.refs.title.innerHTML = title;
this.refs.title.innerHTML = title });
this.post = () => { this.post = () => {
this.openPostForm! this.openPostForm();
};
</script> </script>
</mk-ui-header> </mk-ui-header>