This commit is contained in:
syuilo 2017-02-21 11:44:53 +09:00
parent a64632bba5
commit 5b67681889
12 changed files with 334 additions and 256 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -3,7 +3,9 @@
<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>
<footer data-yield="footer">
<yield from="footer"/>
</footer>
<style>
:scope
display block
@ -44,36 +46,47 @@
</style>
<script>
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.posts = [];
this.on('update', () => {
this.posts.forEach (post) =>
date = (new Date post.created_at).getDate()
month = (new Date post.created_at).getMonth() + 1
post._date = date
post._datetext = month + '月 ' + date + '日'
this.posts.forEach(post => {
const date = new Date(post.created_at).getDate();
const month = new Date(post.created_at).getMonth() + 1;
post._date = 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.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>
</mk-timeline>

View file

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

View file

@ -1,7 +1,9 @@
<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>
<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 }>
@ -9,8 +11,10 @@
<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>
<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>
@ -90,45 +94,48 @@
<script>
this.mixin('i');
this.limit = 30users
this.mode = 'all'
this.limit = 30;
this.mode = 'all';
this.fetching = true
this.more-fetching = false
this.fetching = true;
this.moreFetching = false;
this.on('mount', () => {
@fetch =>
this.trigger('loaded');
this.fetch(() => this.trigger('loaded'));
});
this.fetch = (cb) => {
this.fetching = true
this.update();
obj <~ this.opts.fetch do
this.mode == 'iknow'
@limit
null
this.users = obj.users
this.next = obj.next
this.fetching = false
this.update();
if cb? then cb!
this.fetch = cb => {
this.update({
fetching: true
});
this.opts.fetch(this.mode == 'iknow', this.limit, null, obj => {
this.update({
fetching: false,
users: obj.users,
next: obj.next
});
if (cb) cb();
});
};
this.more = () => {
this.more-fetching = true
this.update();
obj <~ this.opts.fetch do
this.mode == 'iknow'
@limit
@cursor
this.users = this.users.concat obj.users
this.next = obj.next
this.more-fetching = false
this.update();
this.update({
moreFetching: true
});
this.opts.fetch(this.mode == 'iknow', this.limit, this.cursor, obj => {
this.update({
moreFetching: false,
users: this.users.concat(obj.users),
next: obj.next
});
});
};
this.set-mode = (mode) => {
@update do
this.setMode = mode => {
this.update({
mode: mode
@fetch!
});
this.fetch();
};
</script>
</mk-users-list>

View file

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

View file

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

View file

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