#925, #926, and refactoring

This commit is contained in:
syuilo 2017-11-17 01:24:44 +09:00
parent 4129dce95a
commit c614e6f5d7
38 changed files with 358 additions and 216 deletions

View file

@ -2,7 +2,7 @@ import { EventEmitter } from 'eventemitter3';
import * as riot from 'riot';
import signout from './scripts/signout';
import Progress from './scripts/loading';
import Connection from './scripts/home-stream';
import HomeStreamManager from './scripts/streaming/home-stream-manager';
import CONFIG from './scripts/config';
import api from './scripts/api';
@ -33,9 +33,9 @@ export default class MiOS extends EventEmitter {
}
/**
* A connection of home stream
* A connection manager of home stream
*/
public stream: Connection;
public stream: HomeStreamManager;
constructor() {
super();
@ -67,21 +67,27 @@ export default class MiOS extends EventEmitter {
body: JSON.stringify({
i: token
})
}).then(res => { // When success
})
// When success
.then(res => {
// When failed to authenticate user
if (res.status !== 200) {
return signout();
}
// Parse response
res.json().then(i => {
me = i;
me.token = token;
done();
});
}, () => { // When failure
})
// When failure
.catch(() => {
// Render the error screen
document.body.innerHTML = '<mk-error />';
riot.mount('*');
Progress.done();
});
@ -104,6 +110,7 @@ export default class MiOS extends EventEmitter {
// ローカルストレージにキャッシュ
localStorage.setItem('me', JSON.stringify(me));
// 自分の情報が更新されたとき
me.on('updated', () => {
// キャッシュ更新
localStorage.setItem('me', JSON.stringify(me));
@ -112,8 +119,10 @@ export default class MiOS extends EventEmitter {
this.i = me;
// Init home stream connection
this.stream = this.i ? new Connection(this.i) : null;
// Init home stream manager
this.stream = this.isSignedin
? new HomeStreamManager(this.i)
: null;
// Finish init
callback();

View file

@ -1,10 +1,10 @@
import * as riot from 'riot';
import MiOS from './mios';
import ServerStreamManager from './scripts/server-stream-manager';
import RequestsStreamManager from './scripts/requests-stream-manager';
import MessagingIndexStreamManager from './scripts/messaging-index-stream-manager';
import DriveStreamManager from './scripts/drive-stream-manager';
import ServerStreamManager from './scripts/streaming/server-stream-manager';
import RequestsStreamManager from './scripts/streaming/requests-stream-manager';
import MessagingIndexStreamManager from './scripts/streaming/messaging-index-stream-manager';
import DriveStreamManager from './scripts/streaming/drive-stream-manager';
export default (mios: MiOS) => {
(riot as any).mixin('os', {

View file

@ -1,33 +0,0 @@
import * as uuid from 'uuid';
import Connection from './stream';
export default abstract class StreamManager<T extends Connection> {
protected connection: T = null;
/**
*
*/
private users = [];
public abstract getConnection(): T;
public use() {
// ユーザーID生成
const userId = uuid();
this.users.push(userId);
return userId;
}
public dispose(userId) {
this.users = this.users.filter(id => id != userId);
// 誰もコネクションの利用者がいなくなったら
if (this.users.length == 0) {
// コネクションを切断する
this.connection.close();
this.connection = null;
}
}
}

View file

@ -3,12 +3,10 @@ import Stream from './stream';
/**
* Channel stream connection
*/
class Connection extends Stream {
export default class Connection extends Stream {
constructor(channelId) {
super('channel', {
channel: channelId
});
}
}
export default Connection;

View file

@ -3,12 +3,10 @@ import Stream from './stream';
/**
* Drive stream connection
*/
class Connection extends Stream {
export default class Connection extends Stream {
constructor(me) {
super('drive', {
i: me.token
});
}
}
export default Connection;

View file

@ -0,0 +1,20 @@
import StreamManager from './stream-manager';
import Connection from './home-stream';
export default class HomeStreamManager extends StreamManager<Connection> {
private me;
constructor(me) {
super();
this.me = me;
}
public getConnection() {
if (this.connection == null) {
this.connection = new Connection(this.me);
}
return this.connection;
}
}

View file

@ -1,10 +1,10 @@
import Stream from './stream';
import signout from './signout';
import signout from '../signout';
/**
* Home stream connection
*/
class Connection extends Stream {
export default class Connection extends Stream {
constructor(me) {
super('', {
i: me.token
@ -15,13 +15,14 @@ class Connection extends Stream {
this.send({ type: 'alive' });
}, 1000 * 60);
// 自分の情報が更新されたとき
(this as any).on('i_updated', me.update);
// トークンが再生成されたとき
// このままではAPIが利用できないので強制的にサインアウトさせる
(this as any).on('my_token_regenerated', () => {
alert('%i18n:common.my-token-regenerated%');
signout();
});
}
}
export default Connection;

View file

@ -3,12 +3,10 @@ import Stream from './stream';
/**
* Messaging index stream connection
*/
class Connection extends Stream {
export default class Connection extends Stream {
constructor(me) {
super('messaging-index', {
i: me.token
});
}
}
export default Connection;

View file

@ -3,7 +3,7 @@ import Stream from './stream';
/**
* Messaging stream connection
*/
class Connection extends Stream {
export default class Connection extends Stream {
constructor(me, otherparty) {
super('messaging', {
i: me.token,
@ -17,5 +17,3 @@ class Connection extends Stream {
});
}
}
export default Connection;

View file

@ -3,10 +3,8 @@ import Stream from './stream';
/**
* Requests stream connection
*/
class Connection extends Stream {
export default class Connection extends Stream {
constructor() {
super('requests');
}
}
export default Connection;

View file

@ -3,10 +3,8 @@ import Stream from './stream';
/**
* Server stream connection
*/
class Connection extends Stream {
export default class Connection extends Stream {
constructor() {
super('server');
}
}
export default Connection;

View file

@ -0,0 +1,73 @@
import { EventEmitter } from 'eventemitter3';
import * as uuid from 'uuid';
import Connection from './stream';
/**
*
*
*/
export default abstract class StreamManager<T extends Connection> extends EventEmitter {
protected _connection: T = null;
/**
*
*/
private users = [];
protected set connection(connection: T) {
this._connection = connection;
if (this._connection == null) {
this.emit('disconnected');
} else {
this.emit('connected', this._connection);
}
}
protected get connection() {
return this._connection;
}
/**
*
*/
public get hasConnection() {
return this._connection != null;
}
/**
*
*/
public abstract getConnection(): T;
public borrow() {
return this._connection;
}
/**
* IDを発行します
*/
public use() {
// ユーザーID生成
const userId = uuid();
this.users.push(userId);
return userId;
}
/**
*
* @param userId use ID
*/
public dispose(userId) {
this.users = this.users.filter(id => id != userId);
// 誰もコネクションの利用者がいなくなったら
if (this.users.length == 0) {
// コネクションを切断する
this.connection.close();
this.connection = null;
}
}
}

View file

@ -1,25 +1,25 @@
import { EventEmitter } from 'eventemitter3';
import * as ReconnectingWebsocket from 'reconnecting-websocket';
import * as riot from 'riot';
import CONFIG from './config';
import CONFIG from '../config';
/**
* Misskey stream connection
*/
class Connection {
export default class Connection extends EventEmitter {
private state: string;
private buffer: any[];
private socket: ReconnectingWebsocket;
constructor(endpoint, params?) {
// BIND -----------------------------------
super();
//#region BIND
this.onOpen = this.onOpen.bind(this);
this.onClose = this.onClose.bind(this);
this.onMessage = this.onMessage.bind(this);
this.send = this.send.bind(this);
this.close = this.close.bind(this);
// ----------------------------------------
riot.observable(this);
//#endregion
this.state = 'initializing';
this.buffer = [];
@ -42,7 +42,7 @@ class Connection {
*/
private onOpen() {
this.state = 'connected';
(this as any).trigger('_connected_');
this.emit('_connected_');
// バッファーを処理
const _buffer = [].concat(this.buffer); // Shallow copy
@ -57,7 +57,7 @@ class Connection {
*/
private onClose() {
this.state = 'reconnecting';
(this as any).trigger('_closed_');
this.emit('_closed_');
}
/**
@ -66,7 +66,7 @@ class Connection {
private onMessage(message) {
try {
const msg = JSON.parse(message.data);
if (msg.type) (this as any).trigger(msg.type, msg.body);
if (msg.type) this.emit(msg.type, msg.body);
} catch (e) {
// noop
}
@ -93,5 +93,3 @@ class Connection {
this.socket.removeEventListener('message', this.onMessage);
}
}
export default Connection;

View file

@ -162,7 +162,7 @@
</style>
<script>
import MessagingStreamConnection from '../../scripts/messaging-stream';
import MessagingStreamConnection from '../../scripts/streaming/messaging-stream';
this.mixin('i');
this.mixin('api');

View file

@ -50,7 +50,10 @@
<script>
this.mixin('i');
this.mixin('api');
this.mixin('stream');
this.connection = this.stream.getConnection();
this.connectionId = this.stream.use();
this.history = [];
this.fetching = true;
@ -63,11 +66,12 @@
});
});
this.stream.on('signin', this.onSignin);
this.connection.on('signin', this.onSignin);
});
this.on('unmount', () => {
this.stream.off('signin', this.onSignin);
this.connection.off('signin', this.onSignin);
this.stream.dispose(this.connectionId);
});
this.onSignin = signin => {

View file

@ -1,13 +1,13 @@
<mk-stream-indicator>
<p if={ stream.state == 'initializing' }>
<p if={ connection.state == 'initializing' }>
<i class="fa fa-spinner fa-spin"></i>
<span>%i18n:common.tags.mk-stream-indicator.connecting%<mk-ellipsis/></span>
</p>
<p if={ stream.state == 'reconnecting' }>
<p if={ connection.state == 'reconnecting' }>
<i class="fa fa-spinner fa-spin"></i>
<span>%i18n:common.tags.mk-stream-indicator.reconnecting%<mk-ellipsis/></span>
</p>
<p if={ stream.state == 'connected' }>
<p if={ connection.state == 'connected' }>
<i class="fa fa-check"></i>
<span>%i18n:common.tags.mk-stream-indicator.connected%</span>
</p>
@ -38,34 +38,41 @@
import anime from 'animejs';
this.mixin('i');
this.mixin('stream');
this.connection = this.stream.getConnection();
this.connectionId = this.stream.use();
this.on('before-mount', () => {
if (this.stream.state == 'connected') {
if (this.connection.state == 'connected') {
this.root.style.opacity = 0;
}
});
this.stream.on('_connected_', () => {
this.update();
setTimeout(() => {
this.connection.on('_connected_', () => {
this.update();
setTimeout(() => {
anime({
targets: this.root,
opacity: 0,
easing: 'linear',
duration: 200
});
}, 1000);
});
this.connection.on('_closed_', () => {
this.update();
anime({
targets: this.root,
opacity: 0,
opacity: 1,
easing: 'linear',
duration: 200
duration: 100
});
}, 1000);
});
});
this.stream.on('_closed_', () => {
this.update();
anime({
targets: this.root,
opacity: 1,
easing: 'linear',
duration: 100
});
this.on('unmount', () => {
this.stream.dispose(this.connectionId);
});
</script>
</mk-stream-indicator>