This commit is contained in:
syuilo 2017-11-01 00:10:30 +09:00
parent f87ec61e96
commit 346c2959e0
5 changed files with 227 additions and 0 deletions

View File

@ -487,6 +487,9 @@ const endpoints: Endpoint[] = [
{
name: 'channels/show'
},
{
name: 'channels/posts'
},
];
export default endpoints;

View File

@ -0,0 +1,79 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import { default as Channel, IChannel } from '../../models/channel';
import { default as Post, IPost } from '../../models/post';
import serialize from '../../serializers/post';
/**
* Show a posts of a channel
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'limit' parameter
const [limit = 1000, limitErr] = $(params.limit).optional.number().range(1, 1000).$;
if (limitErr) return rej('invalid limit param');
// Get 'since_id' parameter
const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
if (sinceIdErr) return rej('invalid since_id param');
// Get 'max_id' parameter
const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
if (maxIdErr) return rej('invalid max_id param');
// Check if both of since_id and max_id is specified
if (sinceId && maxId) {
return rej('cannot set since_id and max_id');
}
// Get 'channel_id' parameter
const [channelId, channelIdErr] = $(params.channel_id).id().$;
if (channelIdErr) return rej('invalid channel_id param');
// Fetch channel
const channel: IChannel = await Channel.findOne({
_id: channelId
});
if (channel === null) {
return rej('channel not found');
}
//#region Construct query
const sort = {
_id: -1
};
const query = {
channel_id: channel._id
} as any;
if (sinceId) {
sort._id = 1;
query._id = {
$gt: sinceId
};
} else if (maxId) {
query._id = {
$lt: maxId
};
}
//#endregion Construct query
// Issue query
const posts = await Post
.find(query, {
limit: limit,
sort: sort
});
// Serialize
res(await Promise.all(posts.map(async (post) =>
await serialize(post, user)
)));
});

View File

@ -0,0 +1,14 @@
'use strict';
import Stream from './stream';
/**
* Channel stream connection
*/
class Connection extends Stream {
constructor() {
super('channel');
}
}
export default Connection;

View File

@ -2,6 +2,8 @@
<mk-ui ref="ui">
<main if={ !parent.fetching }>
<h1>{ parent.channel.title }</h1>
<mk-channel-post each={ parent.posts } post={ this }/>
<mk-channel-form channel={ parent.channel }/>
</main>
</mk-ui>
<style>
@ -14,12 +16,15 @@
</style>
<script>
import Progress from '../../../common/scripts/loading';
import ChannelStream from '../../../common/scripts/channel-stream';
this.mixin('api');
this.id = this.opts.id;
this.fetching = true;
this.channel = null;
this.posts = null;
this.connection = new ChannelStream();
this.on('mount', () => {
document.documentElement.style.background = '#efefef';
@ -38,6 +43,88 @@
document.title = channel.title + ' | Misskey'
});
this.api('channels/posts', {
channel_id: this.id
}).then(posts => {
this.update({
posts: posts
});
});
});
</script>
</mk-channel-page>
<mk-channel-post>
<header>
<b>{ post.user.name }</b>
</header>
<div>
{ post.text }
</div>
<style>
:scope
display block
margin 0
padding 0
> header
> b
color #008000
</style>
<script>
this.post = this.opts.post;
</script>
</mk-channel-post>
<mk-channel-form>
<p if={ reply }>{ reply.user.name }への返信: (or <a onclick={ clearReply }>キャンセル</a>)</p>
<textarea ref="text" disabled={ wait }></textarea>
<button class={ wait: wait } ref="submit" disabled={ wait || (refs.text.value.length == 0) } onclick={ post }>
{ wait ? 'やってます' : 'やる' }<mk-ellipsis if={ wait }/>
</button>
<style>
:scope
display block
</style>
<script>
this.mixin('api');
this.channel = this.opts.channel;
this.clearReply = () => {
this.update({
reply: null
});
};
this.clear = () => {
this.clearReply();
this.refs.text.value = '';
};
this.post = e => {
this.update({
wait: true
});
this.api('posts/create', {
text: this.refs.text.value,
reply_to_id: this.reply ? this.reply.id : undefined,
channel_id: this.channel.id
}).then(data => {
this.clear();
}).catch(err => {
alert('失敗した');
}).then(() => {
this.update({
wait: false
});
});
};
</script>
</mk-channel-form>

View File

@ -0,0 +1,44 @@
<mk-drive-chooser>
<mk-drive-browser ref="browser" multiple={ parent.multiple }/>
<div>
<button class="upload" title="PCからドライブにファイルをアップロード" onclick={ upload }><i class="fa fa-upload"></i></button>
<button class="cancel" onclick={ close }>キャンセル</button>
<button class="ok" onclick={ parent.ok }>決定</button>
</div>
<style>
:scope
display block
height 100%
</style>
<script>
this.multiple = this.opts.multiple != null ? this.opts.multiple : false;
this.on('mount', () => {
this.refs.browser.on('selected', file => {
this.files = [file];
this.ok();
});
this.refs.browser.on('change-selection', files => {
this.update({
files: files
});
});
});
this.upload = () => {
this.refs.browser.selectLocalFile();
};
this.close = () => {
window.close();
};
this.ok = () => {
window.opener.cb(this.multiple ? this.files : this.files[0]);
window.close();
};
</script>
</mk-drive-chooser>