summaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2020-11-01 22:09:16 +0900
committersyuilo <syuilotan@yahoo.co.jp>2020-11-01 22:09:16 +0900
commit7060625adfa4fe10daefa871510620c34db14987 (patch)
tree03bae495a6301efccc83ee29e2abb00f763b4f1f /src/client
parentメモリリークの一因になってそうだったのでrefを渡すの... (diff)
downloadmisskey-7060625adfa4fe10daefa871510620c34db14987.tar.gz
misskey-7060625adfa4fe10daefa871510620c34db14987.tar.bz2
misskey-7060625adfa4fe10daefa871510620c34db14987.zip
Improve task manager etc
Diffstat (limited to 'src/client')
-rw-r--r--src/client/components/dialog.vue6
-rw-r--r--src/client/components/taskmanager.vue53
-rw-r--r--src/client/directives/follow-append.ts25
-rw-r--r--src/client/os.ts33
-rw-r--r--src/client/pages/test.vue8
-rw-r--r--src/client/themes/_dark.json53
-rw-r--r--src/client/themes/_light.json53
7 files changed, 108 insertions, 23 deletions
diff --git a/src/client/components/dialog.vue b/src/client/components/dialog.vue
index f157a37eac..f8d700202a 100644
--- a/src/client/components/dialog.vue
+++ b/src/client/components/dialog.vue
@@ -169,15 +169,15 @@ export default defineComponent({
font-size: 32px;
&.success {
- color: var(--accent);
+ color: var(--success);
}
&.error {
- color: #ec4137;
+ color: var(--error);
}
&.warning {
- color: #ecb637;
+ color: var(--warn);
}
> * {
diff --git a/src/client/components/taskmanager.vue b/src/client/components/taskmanager.vue
index 29b054d0fa..704e2d3e89 100644
--- a/src/client/components/taskmanager.vue
+++ b/src/client/components/taskmanager.vue
@@ -7,7 +7,7 @@
<MkTab v-model:value="tab" :items="[{ label: 'Windows', value: 'windows', }, { label: 'Stream', value: 'stream', }, { label: 'Stream (Pool)', value: 'streamPool', }, { label: 'API', value: 'api', }]" style="border-bottom: solid 1px var(--divider);"/>
<div class="content">
- <div v-if="tab === 'windows'" class="windows">
+ <div v-if="tab === 'windows'" class="windows" v-follow>
<div class="header">
<div>#ID</div>
<div>Component</div>
@@ -19,7 +19,7 @@
<div><button class="_textButton" @click="killPopup(p)">Kill</button></div>
</div>
</div>
- <div v-if="tab === 'stream'" class="stream">
+ <div v-if="tab === 'stream'" class="stream" v-follow>
<div class="header">
<div>#ID</div>
<div>Ch</div>
@@ -36,7 +36,7 @@
<div>{{ c.out }}</div>
</div>
</div>
- <div v-if="tab === 'streamPool'" class="streamPool">
+ <div v-if="tab === 'streamPool'" class="streamPool" v-follow>
<div class="header">
<div>#ID</div>
<div>Ch</div>
@@ -48,6 +48,18 @@
<div>{{ p.users }}</div>
</div>
</div>
+ <div v-if="tab === 'api'" class="api" v-follow>
+ <div class="header">
+ <div>#ID</div>
+ <div>Endpoint</div>
+ <div>State</div>
+ </div>
+ <div v-for="req in apiRequests">
+ <div>#{{ req.id }}</div>
+ <div>{{ req.endpoint }}</div>
+ <div class="state" :class="req.state">{{ req.state }}</div>
+ </div>
+ </div>
</div>
<footer>
@@ -65,6 +77,7 @@ 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 follow from '@/directives/follow-append';
import * as os from '@/os';
export default defineComponent({
@@ -74,6 +87,10 @@ export default defineComponent({
MkButton,
},
+ directives: {
+ follow
+ },
+
props: {
},
@@ -105,6 +122,7 @@ export default defineComponent({
return {
tab: ref('stream'),
popups: os.popups,
+ apiRequests: os.apiRequests,
connections,
pools,
killPopup,
@@ -125,9 +143,7 @@ export default defineComponent({
flex: 1;
overflow: auto;
- > .windows,
- > .stream,
- > .streamPool {
+ > div {
display: table;
width: 100%;
padding: 16px;
@@ -140,8 +156,31 @@ export default defineComponent({
opacity: 0.7;
}
- > * {
+ > div {
display: table-cell;
+ white-space: nowrap;
+
+ &:not(:last-child) {
+ padding-right: 8px;
+ }
+ }
+ }
+
+ &.api {
+ > div {
+ > .state {
+ &.pending {
+ color: var(--warn);
+ }
+
+ &.success {
+ color: var(--success);
+ }
+
+ &.failed {
+ color: var(--error);
+ }
+ }
}
}
}
diff --git a/src/client/directives/follow-append.ts b/src/client/directives/follow-append.ts
new file mode 100644
index 0000000000..26f9e9f82b
--- /dev/null
+++ b/src/client/directives/follow-append.ts
@@ -0,0 +1,25 @@
+import { Directive } from 'vue';
+import { getScrollContainer, getScrollPosition } from '@/scripts/scroll';
+
+export default {
+ mounted(src, binding, vn) {
+ const ro = new ResizeObserver((entries, observer) => {
+ const pos = getScrollPosition(src);
+ const container = getScrollContainer(src);
+ const viewHeight = container.clientHeight;
+ const height = container.scrollHeight;
+ if (pos + viewHeight > height - 32) {
+ container.scrollTop = height;
+ }
+ });
+
+ ro.observe(src);
+
+ // TODO: 新たにプロパティを作るのをやめMapを使う
+ src._ro_ = ro;
+ },
+
+ unmounted(src, binding, vn) {
+ src._ro_.unobserve(src);
+ }
+} as Directive;
diff --git a/src/client/os.ts b/src/client/os.ts
index 86fdd21b61..a9b56e60f1 100644
--- a/src/client/os.ts
+++ b/src/client/os.ts
@@ -2,7 +2,7 @@ import { Component, defineAsyncComponent, markRaw, reactive, Ref, ref } from 'vu
import { EventEmitter } from 'eventemitter3';
import Stream from '@/scripts/stream';
import { store } from '@/store';
-import { apiUrl } from '@/config';
+import { apiUrl, debug } from '@/config';
import MkPostFormDialog from '@/components/post-form-dialog.vue';
import MkWaitingDialog from '@/components/waiting-dialog.vue';
import { resolve } from '@/router';
@@ -13,28 +13,26 @@ export const isMobile = /mobile|iphone|ipad|android/.test(ua);
export const stream = markRaw(new Stream());
export const pendingApiRequestsCount = ref(0);
+export const apiRequests = ref([]); // for debug
export const windows = new Map();
export function api(endpoint: string, data: Record<string, any> = {}, token?: string | null | undefined) {
pendingApiRequestsCount.value++;
- if (_DEV_) {
- performance.mark(_PERF_PREFIX_ + 'api:begin');
- }
-
const onFinally = () => {
pendingApiRequestsCount.value--;
-
- if (_DEV_) {
- performance.mark(_PERF_PREFIX_ + 'api:end');
-
- performance.measure(_PERF_PREFIX_ + 'api',
- _PERF_PREFIX_ + 'api:begin',
- _PERF_PREFIX_ + 'api:end');
- }
};
+ const log = debug ? reactive({
+ id: apiRequests.value.length,
+ endpoint,
+ state: 'pending'
+ }) : null;
+ if (debug) {
+ apiRequests.value.push(log);
+ }
+
const promise = new Promise((resolve, reject) => {
// Append a credential
if (store.getters.isSignedIn) (data as any).i = store.state.i.token;
@@ -51,10 +49,19 @@ export function api(endpoint: string, data: Record<string, any> = {}, token?: st
if (res.status === 200) {
resolve(body);
+ if (debug) {
+ log.state = 'success';
+ }
} else if (res.status === 204) {
resolve();
+ if (debug) {
+ log.state = 'success';
+ }
} else {
reject(body.error);
+ if (debug) {
+ log.state = 'failed';
+ }
}
}).catch(reject);
});
diff --git a/src/client/pages/test.vue b/src/client/pages/test.vue
index 5a3929d630..bcfe891c8f 100644
--- a/src/client/pages/test.vue
+++ b/src/client/pages/test.vue
@@ -10,6 +10,10 @@
<MkInput v-model:value="dialogBody">
<span>Body</span>
</MkInput>
+ <MkRadio v-model="dialogType" value="info">Info</MkRadio>
+ <MkRadio v-model="dialogType" value="success">Success</MkRadio>
+ <MkRadio v-model="dialogType" value="warning">Warn</MkRadio>
+ <MkRadio v-model="dialogType" value="error">Error</MkRadio>
<MkSwitch v-model:value="dialogCancel">
<span>With cancel button</span>
</MkSwitch>
@@ -133,6 +137,7 @@ import MkButton from '@/components/ui/button.vue';
import MkInput from '@/components/ui/input.vue';
import MkSwitch from '@/components/ui/switch.vue';
import MkTextarea from '@/components/ui/textarea.vue';
+import MkRadio from '@/components/ui/radio.vue';
import * as os from '@/os';
export default defineComponent({
@@ -141,6 +146,7 @@ export default defineComponent({
MkInput,
MkSwitch,
MkTextarea,
+ MkRadio,
},
data() {
@@ -153,6 +159,7 @@ export default defineComponent({
},
dialogTitle: 'Hello',
dialogBody: 'World!',
+ dialogType: 'info',
dialogCancel: false,
dialogCancelByBgClick: true,
dialogInput: false,
@@ -192,6 +199,7 @@ export default defineComponent({
async showDialog() {
this.dialogResult = null;
this.dialogResult = await os.dialog({
+ type: this.dialogType,
title: this.dialogTitle,
text: this.dialogBody,
showCancelButton: this.dialogCancel,
diff --git a/src/client/themes/_dark.json5 b/src/client/themes/_dark.json5
index ce06618aca..ee6d9b49e9 100644
--- a/src/client/themes/_dark.json5
+++ b/src/client/themes/_dark.json5
@@ -56,6 +56,9 @@
wallpaperOverlay: 'rgba(0, 0, 0, 0.5)',
badge: '#31b1ce',
messageBg: ':lighten<5<@bg',
+ success: '#86b300',
+ error: '#ec4137',
+ warn: '#ecb637',
htmlThemeColor: '@bg',
X1: ':alpha<0<@bg',
X2: ':darken<2<@panel',
diff --git a/src/client/themes/_light.json5 b/src/client/themes/_light.json5
index 9862e8fdc6..8821999395 100644
--- a/src/client/themes/_light.json5
+++ b/src/client/themes/_light.json5
@@ -56,6 +56,9 @@
wallpaperOverlay: 'rgba(255, 255, 255, 0.5)',
badge: '#31b1ce',
messageBg: '@panel',
+ success: '#86b300',
+ error: '#ec4137',
+ warn: '#ecb637',
htmlThemeColor: '@bg',
X1: ':alpha<0<@bg',
X2: ':darken<2<@panel',