enhance(frontend): Websocketを使用しないモードを実装
This commit is contained in:
parent
a252151d5d
commit
f0b0be12b0
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { EventEmitter } from 'eventemitter3';
|
||||||
|
import * as Misskey from 'misskey-js';
|
||||||
|
import type { Channels, StreamEvents } from 'misskey-js';
|
||||||
|
|
||||||
|
type AnyOf<T extends Record<any, any>> = T[keyof T];
|
||||||
|
type OmitFirst<T extends any[]> = T extends [any, ...infer R] ? R : never;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Websocket無効化時に使うStreamのモック(なにもしない)
|
||||||
|
*/
|
||||||
|
export class StreamMock extends EventEmitter<StreamEvents> {
|
||||||
|
public readonly state = 'initializing';
|
||||||
|
|
||||||
|
constructor(...args: ConstructorParameters<typeof Misskey.Stream>) {
|
||||||
|
super();
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public useChannel<C extends keyof Channels>(channel: C, params?: Channels[C]['params'], name?: string): ChannelConnectionMock<Channels[C]> {
|
||||||
|
return new ChannelConnectionMock(this, channel, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeSharedConnection(connection: any): void {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeSharedConnectionPool(pool: any): void {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectToChannel(): void {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public send(typeOrPayload: string): void
|
||||||
|
public send(typeOrPayload: string, payload: any): void
|
||||||
|
public send(typeOrPayload: Record<string, any> | any[]): void
|
||||||
|
public send(typeOrPayload: string | Record<string, any> | any[], payload?: any): void {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public ping(): void {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public heartbeat(): void {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public close(): void {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChannelConnectionMock<Channel extends AnyOf<Channels> = any> extends EventEmitter<Channel['events']>{
|
||||||
|
public id = '';
|
||||||
|
|
||||||
|
constructor(stream: StreamMock, ...args: OmitFirst<ConstructorParameters<typeof Misskey.ChannelConnection<Channel>>>) {
|
||||||
|
super();
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public send<T extends keyof Channel['receives']>(type: T, body: Channel['receives'][T]): void {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public dispose(): void {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
|
@ -528,6 +528,7 @@ export class ColdDeviceStorage {
|
||||||
lightTheme,
|
lightTheme,
|
||||||
darkTheme,
|
darkTheme,
|
||||||
syncDeviceDarkMode: true,
|
syncDeviceDarkMode: true,
|
||||||
|
disableWebsocket: false,
|
||||||
plugins: [] as Plugin[],
|
plugins: [] as Plugin[],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@ import * as Misskey from 'misskey-js';
|
||||||
import { markRaw } from 'vue';
|
import { markRaw } from 'vue';
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import { wsOrigin } from '@/config.js';
|
import { wsOrigin } from '@/config.js';
|
||||||
|
import { StreamMock } from '@/scripts/stream-mock.js';
|
||||||
|
import { isEmbedPage } from '@/scripts/embed-page.js';
|
||||||
|
import { ColdDeviceStorage } from '@/store.js';
|
||||||
|
|
||||||
// heart beat interval in ms
|
// heart beat interval in ms
|
||||||
const HEART_BEAT_INTERVAL = 1000 * 60;
|
const HEART_BEAT_INTERVAL = 1000 * 60;
|
||||||
|
@ -18,9 +21,14 @@ let lastHeartbeatCall = 0;
|
||||||
export function useStream(): Misskey.Stream {
|
export function useStream(): Misskey.Stream {
|
||||||
if (stream) return stream;
|
if (stream) return stream;
|
||||||
|
|
||||||
stream = markRaw(new Misskey.Stream(wsOrigin, $i ? {
|
if (isEmbedPage() || ColdDeviceStorage.get('disableWebsocket') === true) {
|
||||||
token: $i.token,
|
stream = markRaw(new StreamMock(wsOrigin, null) as unknown as Misskey.Stream);
|
||||||
} : null));
|
return stream;
|
||||||
|
} else {
|
||||||
|
stream = markRaw(new Misskey.Stream(wsOrigin, $i ? {
|
||||||
|
token: $i.token,
|
||||||
|
} : null));
|
||||||
|
}
|
||||||
|
|
||||||
if (timeoutHeartBeat) window.clearTimeout(timeoutHeartBeat);
|
if (timeoutHeartBeat) window.clearTimeout(timeoutHeartBeat);
|
||||||
timeoutHeartBeat = window.setTimeout(heartbeat, HEART_BEAT_INTERVAL);
|
timeoutHeartBeat = window.setTimeout(heartbeat, HEART_BEAT_INTERVAL);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { type Endpoints } from './api.types.js';
|
import { type Endpoints } from './api.types.js';
|
||||||
import Stream, { Connection } from './streaming.js';
|
import Stream, { Connection } from './streaming.js';
|
||||||
|
import { type StreamEvents } from './streaming.js';
|
||||||
import { type Channels } from './streaming.types.js';
|
import { type Channels } from './streaming.types.js';
|
||||||
import { type Acct } from './acct.js';
|
import { type Acct } from './acct.js';
|
||||||
import * as consts from './consts.js';
|
import * as consts from './consts.js';
|
||||||
|
@ -8,6 +9,7 @@ export type {
|
||||||
Endpoints,
|
Endpoints,
|
||||||
Channels,
|
Channels,
|
||||||
Acct,
|
Acct,
|
||||||
|
StreamEvents,
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -17,7 +17,7 @@ export function urlQuery(obj: Record<string, string | number | boolean | undefin
|
||||||
|
|
||||||
type AnyOf<T extends Record<any, any>> = T[keyof T];
|
type AnyOf<T extends Record<any, any>> = T[keyof T];
|
||||||
|
|
||||||
type StreamEvents = {
|
export type StreamEvents = {
|
||||||
_connected_: void;
|
_connected_: void;
|
||||||
_disconnected_: void;
|
_disconnected_: void;
|
||||||
} & BroadcastEvents;
|
} & BroadcastEvents;
|
||||||
|
|
Loading…
Reference in New Issue