タスクマネージャー(wip)

This commit is contained in:
syuilo 2020-11-01 11:39:38 +09:00
parent b64d3af1f3
commit 75a9ff832a
5 changed files with 139 additions and 11 deletions

View file

@ -0,0 +1,96 @@
<template>
<XWindow ref="window" :initial-width="650" :initial-height="420" :can-resize="true" @closed="$emit('closed')">
<template #header>
<Fa :icon="faTerminal" style="margin-right: 0.5em;"/>Task Manager
</template>
<div class="qljqmnzj">
<MkTab v-model:value="tab" :items="[{ label: 'Stream', value: 'stream', }, { label: 'API', value: 'api', }]"/>
<div v-if="tab === 'stream'" class="stream">
<div class="header">
<div>#ID</div>
<div>Ch</div>
<div>Handle</div>
<div>In</div>
<div>Out</div>
</div>
<div v-for="c in connections">
<div>#{{ c.id }}</div>
<div>{{ c.channel }}</div>
<div v-if="c.users !== null">(shared)<span v-if="c.name">{{ ' ' + c.name }}</span></div>
<div v-else>{{ c.name ? c.name : '<anonymous>' }}</div>
<div>{{ c.in }}</div>
<div>{{ c.out }}</div>
</div>
</div>
</div>
</XWindow>
</template>
<script lang="ts">
import { defineComponent, markRaw, onBeforeUnmount, ref } from 'vue';
import { faTerminal } from '@fortawesome/free-solid-svg-icons';
import XWindow from '@/components/ui/window.vue';
import MkTab from '@/components/tab.vue';
import MkButton from '@/components/ui/button.vue';
import * as os from '@/os';
export default defineComponent({
components: {
XWindow,
MkTab,
MkButton,
},
props: {
},
emits: ['closed'],
setup() {
const connections = ref([]);
const refreshStreamInfo = () => {
console.log(os.stream.sharedConnections, os.stream.nonSharedConnections);
connections.value = markRaw(os.stream.sharedConnections.map(c => ({
id: c.id, name: c.name, channel: c.channel, users: c.pool.users, in: c.inCount, out: c.outCount,
})).concat(os.stream.nonSharedConnections.map(c => ({
id: c.id, name: c.name, channel: c.channel, users: null, in: c.inCount, out: c.outCount,
}))));
connections.value.sort((a, b) => (a.id > b.id) ? 1 : -1);
};
const interval = setInterval(refreshStreamInfo, 1000);
onBeforeUnmount(() => {
clearInterval(interval);
});
return {
tab: 'stream',
connections,
faTerminal,
};
},
});
</script>
<style lang="scss" scoped>
.qljqmnzj {
> .stream {
display: table;
width: 100%;
padding: 8px;
box-sizing: border-box;
> div {
display: table-row;
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
&.header {
opacity: 0.7;
}
> * {
display: table-cell;
}
}
}
}
</style>

View file

@ -14,3 +14,4 @@ export const getLocale = async () => Object.fromEntries((await entries(clientDb.
export const version = _VERSION_; export const version = _VERSION_;
export const instanceName = siteName === 'Misskey' ? host : siteName; export const instanceName = siteName === 'Misskey' ? host : siteName;
export const deckmode = localStorage.getItem('deckmode') === 'true'; export const deckmode = localStorage.getItem('deckmode') === 'true';
export const debug = localStorage.getItem('debug') === 'true';

View file

@ -252,7 +252,7 @@ if (store.getters.isSignedIn) {
} }
} }
const main = stream.useSharedConnection('main'); const main = stream.useSharedConnection('main', 'system');
// 自分の情報が更新されたとき // 自分の情報が更新されたとき
main.on('meUpdated', i => { main.on('meUpdated', i => {

View file

@ -10,22 +10,31 @@
</div> </div>
</div> </div>
<div class="_section"> <div class="_section">
<MkA to="/settings/regedit">RegEdit</MkA> <MkSwitch v-model:value="debug" @update:value="changeDebug">
DEBUG MODE
</MkSwitch>
<div v-if="debug">
<MkA to="/settings/regedit">RegEdit</MkA>
<MkButton @click="taskmanager">Task Manager</MkButton>
</div>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineAsyncComponent, defineComponent } from 'vue';
import { faEllipsisH } from '@fortawesome/free-solid-svg-icons'; import { faEllipsisH } from '@fortawesome/free-solid-svg-icons';
import MkSelect from '@/components/ui/select.vue'; import MkSelect from '@/components/ui/select.vue';
import MkSwitch from '@/components/ui/switch.vue'; import MkSwitch from '@/components/ui/switch.vue';
import MkButton from '@/components/ui/button.vue';
import * as os from '@/os'; import * as os from '@/os';
import { debug } from '@/config';
export default defineComponent({ export default defineComponent({
components: { components: {
MkSelect, MkSelect,
MkSwitch, MkSwitch,
MkButton,
}, },
emits: ['info'], emits: ['info'],
@ -38,6 +47,7 @@ export default defineComponent({
icon: faEllipsisH icon: faEllipsisH
}] }]
}, },
debug
} }
}, },
@ -46,11 +56,22 @@ export default defineComponent({
}, },
methods: { methods: {
changeDebug(v) {
console.log(v);
localStorage.setItem('debug', v.toString());
location.reload();
},
onChangeInjectFeaturedNote(v) { onChangeInjectFeaturedNote(v) {
os.api('i/update', { os.api('i/update', {
injectFeaturedNote: v injectFeaturedNote: v
}); });
}, },
taskmanager() {
os.popup(defineAsyncComponent(() => import('@/components/taskmanager.vue')), {
}, {}, 'closed');
}
} }
}); });
</script> </script>

View file

@ -1,7 +1,7 @@
import autobind from 'autobind-decorator'; import autobind from 'autobind-decorator';
import { EventEmitter } from 'eventemitter3'; import { EventEmitter } from 'eventemitter3';
import ReconnectingWebsocket from 'reconnecting-websocket'; import ReconnectingWebsocket from 'reconnecting-websocket';
import { wsUrl } from '@/config'; import { debug, wsUrl } from '@/config';
import { query as urlQuery } from '../../prelude/url'; import { query as urlQuery } from '../../prelude/url';
/** /**
@ -28,7 +28,7 @@ export default class Stream extends EventEmitter {
} }
@autobind @autobind
public useSharedConnection(channel: string): SharedConnection { public useSharedConnection(channel: string, name?: string): SharedConnection {
let pool = this.sharedConnectionPools.find(p => p.channel === channel); let pool = this.sharedConnectionPools.find(p => p.channel === channel);
if (pool == null) { if (pool == null) {
@ -36,7 +36,7 @@ export default class Stream extends EventEmitter {
this.sharedConnectionPools.push(pool); this.sharedConnectionPools.push(pool);
} }
const connection = new SharedConnection(this, channel, pool); const connection = new SharedConnection(this, channel, pool, name);
this.sharedConnections.push(connection); this.sharedConnections.push(connection);
return connection; return connection;
} }
@ -113,6 +113,7 @@ export default class Stream extends EventEmitter {
for (const c of connections.filter(c => c != null)) { for (const c of connections.filter(c => c != null)) {
c.emit(body.type, Object.freeze(body.body)); c.emit(body.type, Object.freeze(body.body));
if (debug) c.inCount++;
} }
} else { } else {
this.emit(type, Object.freeze(body)); this.emit(type, Object.freeze(body));
@ -142,6 +143,8 @@ export default class Stream extends EventEmitter {
} }
} }
let idCounter = 0;
class Pool { class Pool {
public channel: string; public channel: string;
public id: string; public id: string;
@ -154,7 +157,7 @@ class Pool {
this.channel = channel; this.channel = channel;
this.stream = stream; this.stream = stream;
this.id = Math.random().toString().substr(2, 8); this.id = (++idCounter).toString();
this.stream.on('_disconnected_', this.onStreamDisconnected); this.stream.on('_disconnected_', this.onStreamDisconnected);
} }
@ -216,11 +219,16 @@ abstract class Connection extends EventEmitter {
protected stream: Stream; protected stream: Stream;
public abstract id: string; public abstract id: string;
constructor(stream: Stream, channel: string) { public name?: string; // for debug
public inCount: number = 0; // for debug
public outCount: number = 0; // for debug
constructor(stream: Stream, channel: string, name?: string) {
super(); super();
this.stream = stream; this.stream = stream;
this.channel = channel; this.channel = channel;
this.name = name;
} }
@autobind @autobind
@ -233,6 +241,8 @@ abstract class Connection extends EventEmitter {
type: type, type: type,
body: body body: body
}); });
if (debug) this.outCount++;
} }
public abstract dispose(): void; public abstract dispose(): void;
@ -245,8 +255,8 @@ class SharedConnection extends Connection {
return this.pool.id; return this.pool.id;
} }
constructor(stream: Stream, channel: string, pool: Pool) { constructor(stream: Stream, channel: string, pool: Pool, name?: string) {
super(stream, channel); super(stream, channel, name);
this.pool = pool; this.pool = pool;
this.pool.inc(); this.pool.inc();
@ -273,7 +283,7 @@ class NonSharedConnection extends Connection {
super(stream, channel); super(stream, channel);
this.params = params; this.params = params;
this.id = Math.random().toString().substr(2, 8); this.id = (++idCounter).toString();
this.connect(); this.connect();
} }