tweak client
This commit is contained in:
		| @@ -1,30 +1,46 @@ | ||||
| <template> | ||||
| <MkStickyContainer> | ||||
| 	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template> | ||||
| 	<MkSpacer :content-max="500" :margin-min="16" :margin-max="32"> | ||||
| 		<div v-if="file" class="cxqhhsmd _formRoot"> | ||||
| 			<div class="_formBlock"> | ||||
| 	<MkSpacer v-if="file" :content-max="500" :margin-min="16" :margin-max="32"> | ||||
| 		<div v-if="tab === 'overview'" class="cxqhhsmd _formRoot"> | ||||
| 			<a class="_formBlock thumbnail" :href="file.url" target="_blank"> | ||||
| 				<MkDriveFileThumbnail class="thumbnail" :file="file" fit="contain"/> | ||||
| 				<div class="info"> | ||||
| 					<span style="margin-right: 1em;">{{ file.type }}</span> | ||||
| 					<span>{{ bytes(file.size) }}</span> | ||||
| 					<MkTime :time="file.createdAt" mode="detail" style="display: block;"/> | ||||
| 				</div> | ||||
| 			</a> | ||||
| 			<div class="_formBlock"> | ||||
| 				<MkKeyValue :copy="file.type" oneline style="margin: 1em 0;"> | ||||
| 					<template #key>MIME Type</template> | ||||
| 					<template #value><span class="_monospace">{{ file.type }}</span></template> | ||||
| 				</MkKeyValue> | ||||
| 				<MkKeyValue oneline style="margin: 1em 0;"> | ||||
| 					<template #key>Size</template> | ||||
| 					<template #value><span class="_monospace">{{ bytes(file.size) }}</span></template> | ||||
| 				</MkKeyValue> | ||||
| 				<MkKeyValue :copy="file.id" oneline style="margin: 1em 0;"> | ||||
| 					<template #key>ID</template> | ||||
| 					<template #value><span class="_monospace">{{ file.id }}</span></template> | ||||
| 				</MkKeyValue> | ||||
| 				<MkKeyValue :copy="file.md5" oneline style="margin: 1em 0;"> | ||||
| 					<template #key>MD5</template> | ||||
| 					<template #value><span class="_monospace">{{ file.md5 }}</span></template> | ||||
| 				</MkKeyValue> | ||||
| 				<MkKeyValue oneline style="margin: 1em 0;"> | ||||
| 					<template #key>{{ i18n.ts.createdAt }}</template> | ||||
| 					<template #value><span class="_monospace"><MkTime :time="file.createdAt" mode="detail" style="display: block;"/></span></template> | ||||
| 				</MkKeyValue> | ||||
| 			</div> | ||||
| 			<div class="_formBlock"> | ||||
| 				<MkSwitch v-model="isSensitive" @update:modelValue="toggleIsSensitive">NSFW</MkSwitch> | ||||
| 			</div> | ||||
| 			<FormLink class="_formBlock" :to="file.url" :external="true">Open</FormLink> | ||||
| 			<FormLink class="_formBlock" :to="`/user-info/${file.userId}`">{{ $ts.user }}</FormLink> | ||||
| 			<FormLink class="_formBlock" :to="`/user-info/${file.userId}`">{{ $ts.user }} ({{ acct(file.user) }})</FormLink> | ||||
|  | ||||
| 			<div class="_formBlock"> | ||||
| 				<MkButton full danger @click="del"><i class="fas fa-trash-alt"></i> {{ $ts.delete }}</MkButton> | ||||
| 			</div> | ||||
| 			<div v-if="info" class="_formBlock"> | ||||
| 				<details class="_content rawdata"> | ||||
| 					<pre><code>{{ JSON.stringify(info, null, 2) }}</code></pre> | ||||
| 				</details> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 		<div v-else-if="tab === 'raw'" class="_formRoot"> | ||||
| 			<MkObjectView v-if="info" tall :value="info"> | ||||
| 			</MkObjectView> | ||||
| 		</div> | ||||
| 	</MkSpacer> | ||||
| </MkStickyContainer> | ||||
| @@ -34,13 +50,17 @@ | ||||
| import { computed } from 'vue'; | ||||
| import MkButton from '@/components/ui/button.vue'; | ||||
| import MkSwitch from '@/components/form/switch.vue'; | ||||
| import MkObjectView from '@/components/object-view.vue'; | ||||
| import MkDriveFileThumbnail from '@/components/drive-file-thumbnail.vue'; | ||||
| import MkKeyValue from '@/components/key-value.vue'; | ||||
| import FormLink from '@/components/form/link.vue'; | ||||
| import bytes from '@/filters/bytes'; | ||||
| import * as os from '@/os'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { definePageMetadata } from '@/scripts/page-metadata'; | ||||
| import { acct } from '@/filters/user'; | ||||
|  | ||||
| let tab = $ref('overview'); | ||||
| let file: any = $ref(null); | ||||
| let info: any = $ref(null); | ||||
| let isSensitive: boolean = $ref(false); | ||||
| @@ -74,9 +94,25 @@ async function toggleIsSensitive(v) { | ||||
| 	isSensitive = v; | ||||
| } | ||||
|  | ||||
| const headerActions = $computed(() => []); | ||||
| const headerActions = $computed(() => [{ | ||||
| 	text: i18n.ts.openInNewTab, | ||||
| 	icon: 'fas fa-external-link-alt', | ||||
| 	handler: () => { | ||||
| 		window.open(file.url, '_blank'); | ||||
| 	}, | ||||
| }]); | ||||
|  | ||||
| const headerTabs = $computed(() => []); | ||||
| const headerTabs = $computed(() => [{ | ||||
| 	active: tab === 'overview', | ||||
| 	title: i18n.ts.overview, | ||||
| 	icon: 'fas fa-info-circle', | ||||
| 	onClick: () => { tab = 'overview'; }, | ||||
| }, { | ||||
| 	active: tab === 'raw', | ||||
| 	title: 'Raw data', | ||||
| 	icon: 'fas fa-code', | ||||
| 	onClick: () => { tab = 'raw'; }, | ||||
| }]); | ||||
|  | ||||
| definePageMetadata(computed(() => ({ | ||||
| 	title: file ? i18n.ts.file + ': ' + file.name : i18n.ts.file, | ||||
| @@ -87,19 +123,12 @@ definePageMetadata(computed(() => ({ | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .cxqhhsmd { | ||||
| 	> ._section { | ||||
| 		> .thumbnail { | ||||
| 			height: 150px; | ||||
| 			max-width: 100%; | ||||
| 		} | ||||
| 	> .thumbnail { | ||||
| 		display: block; | ||||
|  | ||||
| 		> .info { | ||||
| 			text-align: center; | ||||
| 			margin-top: 8px; | ||||
| 		} | ||||
| 		 | ||||
| 		> .rawdata { | ||||
| 			overflow: auto; | ||||
| 		> .thumbnail { | ||||
| 			height: 300px; | ||||
| 			max-width: 100%; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -73,7 +73,7 @@ | ||||
| 				<FormLink :to="`https://${host}/manifest.json`" external style="margin-bottom: 8px;">manifest.json</FormLink> | ||||
| 			</FormSection> | ||||
| 		</div> | ||||
| 		<div v-if="tab === 'chart'" class="_formRoot"> | ||||
| 		<div v-else-if="tab === 'chart'" class="_formRoot"> | ||||
| 			<div class="cmhjzshl"> | ||||
| 				<div class="selects"> | ||||
| 					<MkSelect v-model="chartSrc" style="margin: 0 10px 0 0; flex: 1;"> | ||||
| @@ -98,7 +98,7 @@ | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 		<div v-if="tab === 'raw'" class="_formRoot"> | ||||
| 		<div v-else-if="tab === 'raw'" class="_formRoot"> | ||||
| 			<MkObjectView tall :value="instance"> | ||||
| 			</MkObjectView> | ||||
| 		</div> | ||||
| @@ -130,11 +130,11 @@ const props = defineProps<{ | ||||
| }>(); | ||||
|  | ||||
| let tab = $ref('overview'); | ||||
| let chartSrc = $ref('instance-requests'); | ||||
| let meta = $ref<misskey.entities.DetailedInstanceMetadata | null>(null); | ||||
| let instance = $ref<misskey.entities.Instance | null>(null); | ||||
| let suspended = $ref(false); | ||||
| let isBlocked = $ref(false); | ||||
| let chartSrc = $ref('instance-requests'); | ||||
|  | ||||
| async function fetch() { | ||||
| 	if (iAmModerator) { | ||||
|   | ||||
| @@ -3,14 +3,18 @@ | ||||
| 	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template> | ||||
| 	<MkSpacer :content-max="500" :margin-min="16" :margin-max="32"> | ||||
| 		<FormSuspense :p="init"> | ||||
| 			<div class="_formRoot"> | ||||
| 			<div v-if="tab === 'overview'" class="_formRoot"> | ||||
| 				<div class="_formBlock aeakzknw"> | ||||
| 					<MkAvatar class="avatar" :user="user" :show-indicator="true"/> | ||||
| 				</div> | ||||
|  | ||||
| 				<FormLink class="_formBlock" :to="userPage(user)">Profile</FormLink> | ||||
| 				<div v-if="user.url" class="_formLinksGrid _formBlock"> | ||||
| 					<FormLink :to="userPage(user)">Profile</FormLink> | ||||
| 					<FormLink :to="user.url" :external="true">Profile (remote)</FormLink> | ||||
| 				</div> | ||||
| 				<FormLink v-else class="_formBlock" :to="userPage(user)">Profile</FormLink> | ||||
|  | ||||
| 				<FormLink v-if="user.url" class="_formBlock" :to="user.url" :external="true">Profile (remote)</FormLink> | ||||
| 				<FormLink v-if="user.host" class="_formBlock" :to="`/instance-info/${user.host}`">{{ i18n.ts.instanceInfo }}</FormLink> | ||||
|  | ||||
| 				<div class="_formBlock"> | ||||
| 					<MkKeyValue :copy="acct(user)" oneline style="margin: 1em 0;"> | ||||
| @@ -57,7 +61,23 @@ | ||||
|  | ||||
| 					<FormButton v-if="user.host != null" class="_formBlock" @click="updateRemoteUser"><i class="fas fa-sync"></i> {{ $ts.updateRemoteUser }}</FormButton> | ||||
| 				</FormSection> | ||||
|  | ||||
| 			</div> | ||||
| 			<div v-else-if="tab === 'chart'" class="_formRoot"> | ||||
| 				<div class="cmhjzshm"> | ||||
| 					<div class="selects"> | ||||
| 						<MkSelect v-model="chartSrc" style="margin: 0 10px 0 0; flex: 1;"> | ||||
| 							<option value="per-user-notes">{{ $ts.notes }}</option> | ||||
| 						</MkSelect> | ||||
| 					</div> | ||||
| 					<div class="charts"> | ||||
| 						<div class="label">{{ i18n.t('recentNHours', { n: 90 }) }}</div> | ||||
| 						<MkChart class="chart" :src="chartSrc" span="hour" :limit="90" :args="{ user, withoutAll: true }" :detailed="true"></MkChart> | ||||
| 						<div class="label">{{ i18n.t('recentNDays', { n: 90 }) }}</div> | ||||
| 						<MkChart class="chart" :src="chartSrc" span="day" :limit="90" :args="{ user, withoutAll: true }" :detailed="true"></MkChart> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 			<div v-else-if="tab === 'raw'" class="_formRoot"> | ||||
| 				<MkObjectView v-if="info && $i.isAdmin" tall :value="info"> | ||||
| 				</MkObjectView> | ||||
|  | ||||
| @@ -72,6 +92,7 @@ | ||||
| <script lang="ts" setup> | ||||
| import { computed, defineAsyncComponent, defineComponent, watch } from 'vue'; | ||||
| import * as misskey from 'misskey-js'; | ||||
| import MkChart from '@/components/chart.vue'; | ||||
| import MkObjectView from '@/components/object-view.vue'; | ||||
| import FormTextarea from '@/components/form/textarea.vue'; | ||||
| import FormSwitch from '@/components/form/switch.vue'; | ||||
| @@ -79,6 +100,7 @@ import FormLink from '@/components/form/link.vue'; | ||||
| import FormSection from '@/components/form/section.vue'; | ||||
| import FormButton from '@/components/ui/button.vue'; | ||||
| import MkKeyValue from '@/components/key-value.vue'; | ||||
| import MkSelect from '@/components/form/select.vue'; | ||||
| import FormSuspense from '@/components/form/suspense.vue'; | ||||
| import * as os from '@/os'; | ||||
| import number from '@/filters/number'; | ||||
| @@ -93,6 +115,8 @@ const props = defineProps<{ | ||||
| 	userId: string; | ||||
| }>(); | ||||
|  | ||||
| let tab = $ref('overview'); | ||||
| let chartSrc = $ref('per-user-notes'); | ||||
| let user = $ref<null | misskey.entities.UserDetailed>(); | ||||
| let init = $ref(); | ||||
| let info = $ref(); | ||||
| @@ -209,7 +233,22 @@ watch(() => user, () => { | ||||
|  | ||||
| const headerActions = $computed(() => []); | ||||
|  | ||||
| const headerTabs = $computed(() => []); | ||||
| const headerTabs = $computed(() => [{ | ||||
| 	active: tab === 'overview', | ||||
| 	title: i18n.ts.overview, | ||||
| 	icon: 'fas fa-info-circle', | ||||
| 	onClick: () => { tab = 'overview'; }, | ||||
| }, { | ||||
| 	active: tab === 'chart', | ||||
| 	title: i18n.ts.charts, | ||||
| 	icon: 'fas fa-chart-simple', | ||||
| 	onClick: () => { tab = 'chart'; }, | ||||
| }, { | ||||
| 	active: tab === 'raw', | ||||
| 	title: 'Raw data', | ||||
| 	icon: 'fas fa-code', | ||||
| 	onClick: () => { tab = 'raw'; }, | ||||
| }]); | ||||
|  | ||||
| definePageMetadata(computed(() => ({ | ||||
| 	title: user ? acct(user) : i18n.ts.userInfo, | ||||
| @@ -226,4 +265,18 @@ definePageMetadata(computed(() => ({ | ||||
| 		height: 64px; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| .cmhjzshm { | ||||
| 	> .selects { | ||||
| 		display: flex; | ||||
| 		margin: 0 0 16px 0; | ||||
| 	} | ||||
|  | ||||
| 	> .charts { | ||||
| 		> .label { | ||||
| 			margin-bottom: 12px; | ||||
| 			font-weight: bold; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| </style> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo