forked from FoundKeyGang/FoundKey
タスクマネージャー(wip)
This commit is contained in:
parent
b64d3af1f3
commit
75a9ff832a
5 changed files with 139 additions and 11 deletions
96
src/client/components/taskmanager.vue
Normal file
96
src/client/components/taskmanager.vue
Normal 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>
|
|
@ -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';
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -10,22 +10,31 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="_section">
|
<div class="_section">
|
||||||
|
<MkSwitch v-model:value="debug" @update:value="changeDebug">
|
||||||
|
DEBUG MODE
|
||||||
|
</MkSwitch>
|
||||||
|
<div v-if="debug">
|
||||||
<MkA to="/settings/regedit">RegEdit</MkA>
|
<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>
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue