summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2017-11-01 03:17:14 +0900
committersyuilo <syuilotan@yahoo.co.jp>2017-11-01 03:17:14 +0900
commitf37fb38640a31c4b8865a5562628197ff21f3cce (patch)
treec68d1b73aeb8c0c61d6a76ed4577036d4c3c04a5
parentwip (diff)
downloadmisskey-f37fb38640a31c4b8865a5562628197ff21f3cce.tar.gz
misskey-f37fb38640a31c4b8865a5562628197ff21f3cce.tar.bz2
misskey-f37fb38640a31c4b8865a5562628197ff21f3cce.zip
wip
-rw-r--r--docs/setup.en.md1
-rw-r--r--docs/setup.ja.md1
-rw-r--r--locales/en.yml13
-rw-r--r--locales/ja.yml13
-rw-r--r--src/api/endpoints/posts/create.ts7
-rw-r--r--src/api/event.ts6
-rw-r--r--src/api/stream/channel.ts12
-rw-r--r--src/api/streaming.ts22
-rw-r--r--src/config.ts2
-rw-r--r--src/web/app/ch/router.js32
-rw-r--r--src/web/app/ch/script.js18
-rw-r--r--src/web/app/ch/style.styl4
-rw-r--r--src/web/app/ch/tags/channel.tag (renamed from src/web/app/desktop/tags/pages/channel.tag)52
-rw-r--r--src/web/app/ch/tags/index.js2
-rw-r--r--src/web/app/ch/tags/index.tag24
-rw-r--r--src/web/app/common/scripts/channel-stream.js6
-rw-r--r--src/web/app/common/scripts/config.js2
-rw-r--r--src/web/app/desktop/router.js12
-rw-r--r--src/web/app/desktop/tags/index.js2
-rw-r--r--src/web/app/desktop/tags/pages/channels.tag28
-rw-r--r--src/web/app/desktop/tags/timeline.tag2
-rw-r--r--src/web/app/desktop/tags/ui.tag6
-rw-r--r--src/web/app/mobile/tags/timeline.tag2
-rw-r--r--src/web/app/mobile/tags/ui.tag5
-rw-r--r--webpack/webpack.config.ts1
25 files changed, 189 insertions, 86 deletions
diff --git a/docs/setup.en.md b/docs/setup.en.md
index 3e48935346..dbc0599b5a 100644
--- a/docs/setup.en.md
+++ b/docs/setup.en.md
@@ -25,6 +25,7 @@ Note that Misskey uses following subdomains:
* **api**.*{primary domain}*
* **auth**.*{primary domain}*
* **about**.*{primary domain}*
+* **ch**.*{primary domain}*
* **stats**.*{primary domain}*
* **status**.*{primary domain}*
* **dev**.*{primary domain}*
diff --git a/docs/setup.ja.md b/docs/setup.ja.md
index 4f48a08088..602fd9b6a1 100644
--- a/docs/setup.ja.md
+++ b/docs/setup.ja.md
@@ -26,6 +26,7 @@ Misskeyは以下のサブドメインを使います:
* **api**.*{primary domain}*
* **auth**.*{primary domain}*
* **about**.*{primary domain}*
+* **ch**.*{primary domain}*
* **stats**.*{primary domain}*
* **status**.*{primary domain}*
* **dev**.*{primary domain}*
diff --git a/locales/en.yml b/locales/en.yml
index 5c7a1165ba..643649b46c 100644
--- a/locales/en.yml
+++ b/locales/en.yml
@@ -164,6 +164,12 @@ common:
mk-uploader:
waiting: "Waiting"
+ch:
+ tags:
+ mk-index:
+ new: "Create new channel"
+ channel-title: "Channel title"
+
desktop:
tags:
mk-api-info:
@@ -241,7 +247,7 @@ desktop:
mk-ui-header-nav:
home: "Home"
messaging: "Messages"
- channels: "Channels"
+ ch: "Channels"
info: "News"
mk-ui-header-search:
@@ -352,10 +358,6 @@ desktop:
mk-repost-form-window:
title: "Are you sure you want to repost this post?"
- mk-channels-page:
- new: "Create new channel"
- channel-title: "Channel title"
-
mobile:
tags:
mk-drive-file-viewer:
@@ -496,6 +498,7 @@ mobile:
home: "Home"
notifications: "Notifications"
messaging: "Messages"
+ ch: "Channels"
drive: "Drive"
settings: "Settings"
about: "About Misskey"
diff --git a/locales/ja.yml b/locales/ja.yml
index dd76a2b900..9fd7d94f0b 100644
--- a/locales/ja.yml
+++ b/locales/ja.yml
@@ -164,6 +164,12 @@ common:
mk-uploader:
waiting: "待機中"
+ch:
+ tags:
+ mk-index:
+ new: "チャンネルを作成"
+ channel-title: "チャンネルのタイトル"
+
desktop:
tags:
mk-api-info:
@@ -241,7 +247,7 @@ desktop:
mk-ui-header-nav:
home: "ホーム"
messaging: "メッセージ"
- channels: "チャンネル"
+ ch: "チャンネル"
info: "お知らせ"
mk-ui-header-search:
@@ -352,10 +358,6 @@ desktop:
mk-repost-form-window:
title: "この投稿をRepostしますか?"
- mk-channels-page:
- new: "チャンネルを作成"
- channel-title: "チャンネルのタイトル"
-
mobile:
tags:
mk-drive-file-viewer:
@@ -496,6 +498,7 @@ mobile:
home: "ホーム"
notifications: "通知"
messaging: "メッセージ"
+ ch: "チャンネル"
search: "検索"
drive: "ドライブ"
settings: "設定"
diff --git a/src/api/endpoints/posts/create.ts b/src/api/endpoints/posts/create.ts
index 183cabf135..34265dcbc3 100644
--- a/src/api/endpoints/posts/create.ts
+++ b/src/api/endpoints/posts/create.ts
@@ -13,7 +13,7 @@ import Watching from '../../models/post-watching';
import serialize from '../../serializers/post';
import notify from '../../common/notify';
import watch from '../../common/watch-post';
-import event from '../../event';
+import { default as event, publishChannelStream } from '../../event';
import config from '../../../conf';
/**
@@ -258,6 +258,11 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
// Publish event to myself's stream
event(user._id, 'post', postObj);
+ // Publish event to channel
+ if (channel) {
+ publishChannelStream(channel._id, 'post', postObj);
+ }
+
// Fetch all followers
const followers = await Following
.find({
diff --git a/src/api/event.ts b/src/api/event.ts
index 9613a9f7cc..909b0d2556 100644
--- a/src/api/event.ts
+++ b/src/api/event.ts
@@ -25,6 +25,10 @@ class MisskeyEvent {
this.publish(`messaging-stream:${userId}-${otherpartyId}`, type, typeof value === 'undefined' ? null : value);
}
+ public publishChannelStream(channelId: ID, type: string, value?: any): void {
+ this.publish(`channel-stream:${channelId}`, type, typeof value === 'undefined' ? null : value);
+ }
+
private publish(channel: string, type: string, value?: any): void {
const message = value == null ?
{ type: type } :
@@ -41,3 +45,5 @@ export default ev.publishUserStream.bind(ev);
export const publishPostStream = ev.publishPostStream.bind(ev);
export const publishMessagingStream = ev.publishMessagingStream.bind(ev);
+
+export const publishChannelStream = ev.publishChannelStream.bind(ev);
diff --git a/src/api/stream/channel.ts b/src/api/stream/channel.ts
new file mode 100644
index 0000000000..d67d77cbf4
--- /dev/null
+++ b/src/api/stream/channel.ts
@@ -0,0 +1,12 @@
+import * as websocket from 'websocket';
+import * as redis from 'redis';
+
+export default function(request: websocket.request, connection: websocket.connection, subscriber: redis.RedisClient): void {
+ const channel = request.resourceURL.query.channel;
+
+ // Subscribe channel stream
+ subscriber.subscribe(`misskey:channel-stream:${channel}`);
+ subscriber.on('message', (_, data) => {
+ connection.send(data);
+ });
+}
diff --git a/src/api/streaming.ts b/src/api/streaming.ts
index db600013b9..0e512fb210 100644
--- a/src/api/streaming.ts
+++ b/src/api/streaming.ts
@@ -9,6 +9,7 @@ import isNativeToken from './common/is-native-token';
import homeStream from './stream/home';
import messagingStream from './stream/messaging';
import serverStream from './stream/server';
+import channelStream from './stream/channel';
module.exports = (server: http.Server) => {
/**
@@ -26,14 +27,6 @@ module.exports = (server: http.Server) => {
return;
}
- const user = await authenticate(request.resourceURL.query.i);
-
- if (user == null) {
- connection.send('authentication-failed');
- connection.close();
- return;
- }
-
// Connect to Redis
const subscriber = redis.createClient(
config.redis.port, config.redis.host);
@@ -43,6 +36,19 @@ module.exports = (server: http.Server) => {
subscriber.quit();
});
+ if (request.resourceURL.pathname === '/channel') {
+ channelStream(request, connection, subscriber);
+ return;
+ }
+
+ const user = await authenticate(request.resourceURL.query.i);
+
+ if (user == null) {
+ connection.send('authentication-failed');
+ connection.close();
+ return;
+ }
+
const channel =
request.resourceURL.pathname === '/' ? homeStream :
request.resourceURL.pathname === '/messaging' ? messagingStream :
diff --git a/src/config.ts b/src/config.ts
index 46a93f5fef..18017e9740 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -88,6 +88,7 @@ type Mixin = {
api_url: string;
auth_url: string;
about_url: string;
+ ch_url: stirng;
stats_url: string;
status_url: string;
dev_url: string;
@@ -122,6 +123,7 @@ export default function load() {
mixin.secondary_scheme = config.secondary_url.substr(0, config.secondary_url.indexOf('://'));
mixin.api_url = `${mixin.scheme}://api.${mixin.host}`;
mixin.auth_url = `${mixin.scheme}://auth.${mixin.host}`;
+ mixin.ch_url = `${mixin.scheme}://ch.${mixin.host}`;
mixin.dev_url = `${mixin.scheme}://dev.${mixin.host}`;
mixin.about_url = `${mixin.scheme}://about.${mixin.host}`;
mixin.stats_url = `${mixin.scheme}://stats.${mixin.host}`;
diff --git a/src/web/app/ch/router.js b/src/web/app/ch/router.js
new file mode 100644
index 0000000000..424158f403
--- /dev/null
+++ b/src/web/app/ch/router.js
@@ -0,0 +1,32 @@
+import * as riot from 'riot';
+const route = require('page');
+let page = null;
+
+export default me => {
+ route('/', index);
+ route('/:channel', channel);
+ route('*', notFound);
+
+ function index() {
+ mount(document.createElement('mk-index'));
+ }
+
+ function channel(ctx) {
+ const el = document.createElement('mk-channel');
+ el.setAttribute('id', ctx.params.channel);
+ mount(el);
+ }
+
+ function notFound() {
+ mount(document.createElement('mk-not-found'));
+ }
+
+ // EXEC
+ route();
+};
+
+function mount(content) {
+ if (page) page.unmount();
+ const body = document.getElementById('app');
+ page = riot.mount(body.appendChild(content))[0];
+}
diff --git a/src/web/app/ch/script.js b/src/web/app/ch/script.js
new file mode 100644
index 0000000000..760d405c52
--- /dev/null
+++ b/src/web/app/ch/script.js
@@ -0,0 +1,18 @@
+/**
+ * Channels
+ */
+
+// Style
+import './style.styl';
+
+require('./tags');
+import init from '../init';
+import route from './router';
+
+/**
+ * init
+ */
+init(me => {
+ // Start routing
+ route(me);
+});
diff --git a/src/web/app/ch/style.styl b/src/web/app/ch/style.styl
new file mode 100644
index 0000000000..2fc3ac3fca
--- /dev/null
+++ b/src/web/app/ch/style.styl
@@ -0,0 +1,4 @@
+@import "../base"
+
+html
+ background #efefef
diff --git a/src/web/app/desktop/tags/pages/channel.tag b/src/web/app/ch/tags/channel.tag
index a14c0648c4..b16844b8bc 100644
--- a/src/web/app/desktop/tags/pages/channel.tag
+++ b/src/web/app/ch/tags/channel.tag
@@ -1,14 +1,19 @@
-<mk-channel-page>
- <mk-ui ref="ui">
- <main if={ !parent.fetching }>
- <h1>{ parent.channel.title }</h1>
- <virtual if={ parent.posts }>
- <mk-channel-post each={ parent.posts.reverse() } post={ this } form={ parent.refs.form }/>
- </virtual>
- <hr>
- <mk-channel-form channel={ parent.channel } ref="form"/>
- </main>
- </mk-ui>
+<mk-channel>
+ <main if={ !fetching }>
+ <h1>{ channel.title }</h1>
+ <virtual if={ posts }>
+ <mk-channel-post each={ posts.slice().reverse() } post={ this } form={ parent.refs.form }/>
+ </virtual>
+ <hr>
+ <mk-channel-form if={ SIGNIN } channel={ channel } ref="form"/>
+ <div if={ !SIGNIN }>
+ <p>参加するには<a href={ CONFIG.url }>ログインまたは新規登録</a>してください</p>
+ </div>
+ <hr>
+ <footer>
+ <small>Misskey ver { version } (葵 aoi)</small>
+ </footer>
+ </main>
<style>
:scope
display block
@@ -20,16 +25,18 @@
color #f00
</style>
<script>
- import Progress from '../../../common/scripts/loading';
- import ChannelStream from '../../../common/scripts/channel-stream';
+ import Progress from '../../common/scripts/loading';
+ import ChannelStream from '../../common/scripts/channel-stream';
+ this.mixin('i');
this.mixin('api');
this.id = this.opts.id;
this.fetching = true;
this.channel = null;
this.posts = null;
- this.connection = new ChannelStream();
+ this.connection = new ChannelStream(this.id);
+ this.version = VERSION;
this.on('mount', () => {
document.documentElement.style.background = '#efefef';
@@ -56,9 +63,22 @@
posts: posts
});
});
+
+ this.connection.on('post', this.onPost);
+ });
+
+ this.on('unmount', () => {
+ this.connection.off('post', this.onPost);
+ this.connection.close();
});
+
+ this.onPost = post => {
+ this.posts.unshift(post);
+ this.update();
+ };
+
</script>
-</mk-channel-page>
+</mk-channel>
<mk-channel-post>
<header>
@@ -127,7 +147,7 @@
</style>
<script>
- import CONFIG from '../../../common/scripts/config';
+ import CONFIG from '../../common/scripts/config';
this.mixin('api');
diff --git a/src/web/app/ch/tags/index.js b/src/web/app/ch/tags/index.js
new file mode 100644
index 0000000000..1e99ccd43e
--- /dev/null
+++ b/src/web/app/ch/tags/index.js
@@ -0,0 +1,2 @@
+require('./index.tag');
+require('./channel.tag');
diff --git a/src/web/app/ch/tags/index.tag b/src/web/app/ch/tags/index.tag
new file mode 100644
index 0000000000..1c0a037c2d
--- /dev/null
+++ b/src/web/app/ch/tags/index.tag
@@ -0,0 +1,24 @@
+<mk-index>
+ <button onclick={ new }>%i18n:ch.tags.mk-index.new%</button>
+ <style>
+ :scope
+ display block
+
+ </style>
+ <script>
+ this.mixin('api');
+
+ this.on('mount', () => {
+ });
+
+ this.new = () => {
+ const title = window.prompt('%i18n:ch.tags.mk-index.channel-title%');
+
+ this.api('channels/create', {
+ title: title
+ }).then(channel => {
+ location.href = '/' + channel.id;
+ });
+ };
+ </script>
+</mk-index>
diff --git a/src/web/app/common/scripts/channel-stream.js b/src/web/app/common/scripts/channel-stream.js
index 38e7d91132..17944dbe45 100644
--- a/src/web/app/common/scripts/channel-stream.js
+++ b/src/web/app/common/scripts/channel-stream.js
@@ -6,8 +6,10 @@ import Stream from './stream';
* Channel stream connection
*/
class Connection extends Stream {
- constructor() {
- super('channel');
+ constructor(channelId) {
+ super('channel', {
+ channel: channelId
+ });
}
}
diff --git a/src/web/app/common/scripts/config.js b/src/web/app/common/scripts/config.js
index 75a7abba29..c5015622f0 100644
--- a/src/web/app/common/scripts/config.js
+++ b/src/web/app/common/scripts/config.js
@@ -6,6 +6,7 @@ const host = isRoot ? Url.host : Url.host.substring(Url.host.indexOf('.') + 1, U
const scheme = Url.protocol;
const url = `${scheme}//${host}`;
const apiUrl = `${scheme}//api.${host}`;
+const chUrl = `${scheme}//ch.${host}`;
const devUrl = `${scheme}//dev.${host}`;
const aboutUrl = `${scheme}//about.${host}`;
const statsUrl = `${scheme}//stats.${host}`;
@@ -16,6 +17,7 @@ export default {
scheme,
url,
apiUrl,
+ chUrl,
devUrl,
aboutUrl,
statsUrl,
diff --git a/src/web/app/desktop/router.js b/src/web/app/desktop/router.js
index df67bb7b7c..977e3fa9a6 100644
--- a/src/web/app/desktop/router.js
+++ b/src/web/app/desktop/router.js
@@ -10,8 +10,6 @@ export default me => {
route('/', index);
route('/selectdrive', selectDrive);
route('/i>mentions', mentions);
- route('/channel', channels);
- route('/channel/:channel', channel);
route('/post::post', post);
route('/search::query', search);
route('/:user', user.bind(null, 'home'));
@@ -57,16 +55,6 @@ export default me => {
mount(el);
}
- function channel(ctx) {
- const el = document.createElement('mk-channel-page');
- el.setAttribute('id', ctx.params.channel);
- mount(el);
- }
-
- function channels() {
- mount(document.createElement('mk-channels-page'));
- }
-
function selectDrive() {
mount(document.createElement('mk-selectdrive-page'));
}
diff --git a/src/web/app/desktop/tags/index.js b/src/web/app/desktop/tags/index.js
index 0b92d8c236..37fdfe37e4 100644
--- a/src/web/app/desktop/tags/index.js
+++ b/src/web/app/desktop/tags/index.js
@@ -61,8 +61,6 @@ require('./pages/user.tag');
require('./pages/post.tag');
require('./pages/search.tag');
require('./pages/not-found.tag');
-require('./pages/channel.tag');
-require('./pages/channels.tag');
require('./pages/selectdrive.tag');
require('./autocomplete-suggestion.tag');
require('./progress-dialog.tag');
diff --git a/src/web/app/desktop/tags/pages/channels.tag b/src/web/app/desktop/tags/pages/channels.tag
deleted file mode 100644
index 220f1ca50e..0000000000
--- a/src/web/app/desktop/tags/pages/channels.tag
+++ /dev/null
@@ -1,28 +0,0 @@
-<mk-channels-page>
- <mk-ui ref="ui">
- <main>
- <button onclick={ parent.new }>%i18n:desktop.tags.mk-channels-page.new%</button>
- </main>
- </mk-ui>
- <style>
- :scope
- display block
-
- </style>
- <script>
- this.mixin('api');
-
- this.on('mount', () => {
- });
-
- this.new = () => {
- const title = window.prompt('%i18n:desktop.tags.mk-channels-page.channel-title%');
-
- this.api('channels/create', {
- title: title
- }).then(channel => {
- location.href = '/channel/' + channel.id;
- });
- };
- </script>
-</mk-channels-page>
diff --git a/src/web/app/desktop/tags/timeline.tag b/src/web/app/desktop/tags/timeline.tag
index 17b2c66dc8..64b64f902f 100644
--- a/src/web/app/desktop/tags/timeline.tag
+++ b/src/web/app/desktop/tags/timeline.tag
@@ -112,7 +112,7 @@
</header>
<div class="body">
<div class="text" ref="text">
- <p class="channel" if={ p.channel != null }><a href={ '/channel/' + p.channel.id }>{ p.channel.title }</a>:</p>
+ <p class="channel" if={ p.channel != null }><a href={ CONFIG.chUrl + '/' + p.channel.id } target="_blank">{ p.channel.title }</a>:</p>
<a class="reply" if={ p.reply_to }>
<i class="fa fa-reply"></i>
</a>
diff --git a/src/web/app/desktop/tags/ui.tag b/src/web/app/desktop/tags/ui.tag
index 7527358dce..3123c34f4f 100644
--- a/src/web/app/desktop/tags/ui.tag
+++ b/src/web/app/desktop/tags/ui.tag
@@ -335,10 +335,10 @@
</a>
</li>
</virtual>
- <li class="channels">
- <a href={ CONFIG.url + '/channel' }>
+ <li class="ch">
+ <a href={ CONFIG.chUrl } target="_blank">
<i class="fa fa-television"></i>
- <p>%i18n:desktop.tags.mk-ui-header-nav.channels%</p>
+ <p>%i18n:desktop.tags.mk-ui-header-nav.ch%</p>
</a>
</li>
<li class="info">
diff --git a/src/web/app/mobile/tags/timeline.tag b/src/web/app/mobile/tags/timeline.tag
index b26a5cb108..ad18521df6 100644
--- a/src/web/app/mobile/tags/timeline.tag
+++ b/src/web/app/mobile/tags/timeline.tag
@@ -164,7 +164,7 @@
</header>
<div class="body">
<div class="text" ref="text">
- <p class="channel" if={ p.channel != null }><a href={ '/channel/' + p.channel.id }>{ p.channel.title }</a>:</p>
+ <p class="channel" if={ p.channel != null }><a href={ CONFIG.chUrl + '/' + p.channel.id } target="_blank">{ p.channel.title }</a>:</p>
<a class="reply" if={ p.reply_to }>
<i class="fa fa-reply"></i>
</a>
diff --git a/src/web/app/mobile/tags/ui.tag b/src/web/app/mobile/tags/ui.tag
index fb8cbcdbd2..b2d96f6b8b 100644
--- a/src/web/app/mobile/tags/ui.tag
+++ b/src/web/app/mobile/tags/ui.tag
@@ -231,10 +231,11 @@
<li><a href="/i/messaging"><i class="fa fa-comments-o"></i>%i18n:mobile.tags.mk-ui-nav.messaging%<i class="i fa fa-circle" if={ hasUnreadMessagingMessages }></i><i class="fa fa-angle-right"></i></a></li>
</ul>
<ul>
- <li><a onclick={ search }><i class="fa fa-search"></i>%i18n:mobile.tags.mk-ui-nav.search%<i class="fa fa-angle-right"></i></a></li>
+ <li><a href={ CONFIG.chUrl } target="_blank"><i class="fa fa-television"></i>%i18n:mobile.tags.mk-ui-nav.ch%<i class="fa fa-angle-right"></i></a></li>
+ <li><a href="/i/drive"><i class="fa fa-cloud"></i>%i18n:mobile.tags.mk-ui-nav.drive%<i class="fa fa-angle-right"></i></a></li>
</ul>
<ul>
- <li><a href="/i/drive"><i class="fa fa-cloud"></i>%i18n:mobile.tags.mk-ui-nav.drive%<i class="fa fa-angle-right"></i></a></li>
+ <li><a onclick={ search }><i class="fa fa-search"></i>%i18n:mobile.tags.mk-ui-nav.search%<i class="fa fa-angle-right"></i></a></li>
</ul>
<ul>
<li><a href="/i/settings"><i class="fa fa-cog"></i>%i18n:mobile.tags.mk-ui-nav.settings%<i class="fa fa-angle-right"></i></a></li>
diff --git a/webpack/webpack.config.ts b/webpack/webpack.config.ts
index 5199285d55..066df18157 100644
--- a/webpack/webpack.config.ts
+++ b/webpack/webpack.config.ts
@@ -16,6 +16,7 @@ module.exports = langs.map(([lang, locale]) => {
const entry = {
desktop: './src/web/app/desktop/script.js',
mobile: './src/web/app/mobile/script.js',
+ ch: './src/web/app/ch/script.js',
stats: './src/web/app/stats/script.js',
status: './src/web/app/status/script.js',
dev: './src/web/app/dev/script.js',