enhance(client): tweak ui
This commit is contained in:
		
							parent
							
								
									e159f15600
								
							
						
					
					
						commit
						616b18a9e5
					
				
					 21 changed files with 393 additions and 323 deletions
				
			
		|  | @ -743,7 +743,7 @@ online: "オンライン" | ||||||
| active: "アクティブ" | active: "アクティブ" | ||||||
| offline: "オフライン" | offline: "オフライン" | ||||||
| notRecommended: "非推奨" | notRecommended: "非推奨" | ||||||
| botProtection: "Bot防御" | botProtection: "Botプロテクション" | ||||||
| instanceBlocking: "インスタンスブロック" | instanceBlocking: "インスタンスブロック" | ||||||
| selectAccount: "アカウントを選択" | selectAccount: "アカウントを選択" | ||||||
| enabled: "有効" | enabled: "有効" | ||||||
|  | @ -754,7 +754,7 @@ administration: "管理" | ||||||
| accounts: "アカウント" | accounts: "アカウント" | ||||||
| switch: "切り替え" | switch: "切り替え" | ||||||
| noMaintainerInformationWarning: "管理者情報が設定されていません。" | noMaintainerInformationWarning: "管理者情報が設定されていません。" | ||||||
| noBotProtectionWarning: "Bot防御が設定されていません。" | noBotProtectionWarning: "Botプロテクションが設定されていません。" | ||||||
| configure: "設定する" | configure: "設定する" | ||||||
| postToGallery: "ギャラリーへ投稿" | postToGallery: "ギャラリーへ投稿" | ||||||
| gallery: "ギャラリー" | gallery: "ギャラリー" | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								packages/client/@types/vue.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								packages/client/@types/vue.d.ts
									
										
									
									
										vendored
									
									
								
							|  | @ -1,3 +1,5 @@ | ||||||
|  | /// <reference types="vue/macros-global" />
 | ||||||
|  | 
 | ||||||
| declare module '*.vue' { | declare module '*.vue' { | ||||||
| 	import type { DefineComponent } from 'vue'; | 	import type { DefineComponent } from 'vue'; | ||||||
| 	const component: DefineComponent<{}, {}, any>; | 	const component: DefineComponent<{}, {}, any>; | ||||||
|  |  | ||||||
|  | @ -116,7 +116,7 @@ | ||||||
| 		"v-debounce": "0.1.2", | 		"v-debounce": "0.1.2", | ||||||
| 		"vanilla-tilt": "1.7.2", | 		"vanilla-tilt": "1.7.2", | ||||||
| 		"vue": "3.2.26", | 		"vue": "3.2.26", | ||||||
| 		"vue-loader": "16.8.3", | 		"vue-loader": "17.0.0", | ||||||
| 		"vue-prism-editor": "2.0.0-alpha.2", | 		"vue-prism-editor": "2.0.0-alpha.2", | ||||||
| 		"vue-router": "4.0.5", | 		"vue-router": "4.0.5", | ||||||
| 		"vue-style-loader": "4.1.3", | 		"vue-style-loader": "4.1.3", | ||||||
|  |  | ||||||
|  | @ -7,12 +7,7 @@ | ||||||
| </div> | </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts" setup> | ||||||
| import { defineComponent } from 'vue'; |  | ||||||
| 
 |  | ||||||
| export default defineComponent({ |  | ||||||
| 
 |  | ||||||
| }); |  | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
|  |  | ||||||
							
								
								
									
										27
									
								
								packages/client/src/components/form/split.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								packages/client/src/components/form/split.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | ||||||
|  | <template> | ||||||
|  | <div class="terlnhxf _formBlock"> | ||||||
|  | 	<slot></slot> | ||||||
|  | </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script lang="ts" setup> | ||||||
|  | const props = withDefaults(defineProps<{ | ||||||
|  | 	minWidth: number; | ||||||
|  | }>(), { | ||||||
|  |   minWidth: 210, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const minWidth = props.minWidth + 'px'; | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .terlnhxf { | ||||||
|  | 	display: grid; | ||||||
|  | 	grid-template-columns: repeat(auto-fill, minmax(v-bind('minWidth'), 1fr)); | ||||||
|  | 	grid-gap: 12px; | ||||||
|  | 
 | ||||||
|  | 	> ::v-deep(*) { | ||||||
|  | 		margin: 0 !important; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | </style> | ||||||
|  | @ -13,7 +13,8 @@ | ||||||
| 		<i class="check fas fa-check"></i> | 		<i class="check fas fa-check"></i> | ||||||
| 	</span> | 	</span> | ||||||
| 	<span class="label"> | 	<span class="label"> | ||||||
| 		<span @click="toggle"><slot></slot></span> | 		<!-- TODO: 無名slotの方は廃止 --> | ||||||
|  | 		<span @click="toggle"><slot name="label"></slot><slot></slot></span> | ||||||
| 		<p class="caption"><slot name="caption"></slot></p> | 		<p class="caption"><slot name="caption"></slot></p> | ||||||
| 	</span> | 	</span> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| <template> | <template> | ||||||
| <XModalWindow ref="dialog" | <XModalWindow ref="dialogEl" | ||||||
| 	:with-ok-button="true" | 	:with-ok-button="true" | ||||||
| 	:ok-button-disabled="selected == null" | 	:ok-button-disabled="selected == null" | ||||||
| 	@click="cancel()" | 	@click="cancel()" | ||||||
|  | @ -8,20 +8,20 @@ | ||||||
| 	@closed="$emit('closed')" | 	@closed="$emit('closed')" | ||||||
| > | > | ||||||
| 	<template #header>{{ $ts.selectUser }}</template> | 	<template #header>{{ $ts.selectUser }}</template> | ||||||
| 	<div class="tbhwbxda _monolithic_"> | 	<div class="tbhwbxda"> | ||||||
| 		<div class="_section"> | 		<div class="form"> | ||||||
| 			<div class="_inputSplit"> | 			<FormSplit :min-width="170"> | ||||||
| 				<MkInput ref="username" v-model="username" class="input" @update:modelValue="search"> | 				<MkInput ref="usernameEl" v-model="username" @update:modelValue="search"> | ||||||
| 					<template #label>{{ $ts.username }}</template> | 					<template #label>{{ $ts.username }}</template> | ||||||
| 					<template #prefix>@</template> | 					<template #prefix>@</template> | ||||||
| 				</MkInput> | 				</MkInput> | ||||||
| 				<MkInput v-model="host" class="input" @update:modelValue="search"> | 				<MkInput v-model="host" @update:modelValue="search"> | ||||||
| 					<template #label>{{ $ts.host }}</template> | 					<template #label>{{ $ts.host }}</template> | ||||||
| 					<template #prefix>@</template> | 					<template #prefix>@</template> | ||||||
| 				</MkInput> | 				</MkInput> | ||||||
| 			</div> | 			</FormSplit> | ||||||
| 		</div> | 		</div> | ||||||
| 		<div v-if="username != '' || host != ''" class="_section result" :class="{ hit: users.length > 0 }"> | 		<div v-if="username != '' || host != ''" class="result" :class="{ hit: users.length > 0 }"> | ||||||
| 			<div v-if="users.length > 0" class="users"> | 			<div v-if="users.length > 0" class="users"> | ||||||
| 				<div v-for="user in users" :key="user.id" class="user" :class="{ selected: selected && selected.id === user.id }" @click="selected = user" @dblclick="ok()"> | 				<div v-for="user in users" :key="user.id" class="user" :class="{ selected: selected && selected.id === user.id }" @click="selected = user" @dblclick="ok()"> | ||||||
| 					<MkAvatar :user="user" class="avatar" :show-indicator="true"/> | 					<MkAvatar :user="user" class="avatar" :show-indicator="true"/> | ||||||
|  | @ -35,7 +35,7 @@ | ||||||
| 				<span>{{ $ts.noUsers }}</span> | 				<span>{{ $ts.noUsers }}</span> | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
| 		<div v-if="username == '' && host == ''" class="_section recent"> | 		<div v-if="username == '' && host == ''" class="recent"> | ||||||
| 			<div class="users"> | 			<div class="users"> | ||||||
| 				<div v-for="user in recentUsers" :key="user.id" class="user" :class="{ selected: selected && selected.id === user.id }" @click="selected = user" @dblclick="ok()"> | 				<div v-for="user in recentUsers" :key="user.id" class="user" :class="{ selected: selected && selected.id === user.id }" @click="selected = user" @dblclick="ok()"> | ||||||
| 					<MkAvatar :user="user" class="avatar" :show-indicator="true"/> | 					<MkAvatar :user="user" class="avatar" :show-indicator="true"/> | ||||||
|  | @ -50,87 +50,89 @@ | ||||||
| </XModalWindow> | </XModalWindow> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts" setup> | ||||||
| import { defineComponent } from 'vue'; | import { nextTick, onMounted } from 'vue'; | ||||||
| import MkInput from './form/input.vue'; | import * as misskey from 'misskey-js'; | ||||||
|  | import MkInput from '@/components/form/input.vue'; | ||||||
|  | import FormSplit from '@/components/form/split.vue'; | ||||||
| import XModalWindow from '@/components/ui/modal-window.vue'; | import XModalWindow from '@/components/ui/modal-window.vue'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
|  | import { defaultStore } from '@/store'; | ||||||
| 
 | 
 | ||||||
| export default defineComponent({ | const emit = defineEmits<{ | ||||||
| 	components: { |   (e: 'ok', selected: misskey.entities.UserDetailed): void; | ||||||
| 		MkInput, |   (e: 'cancel'): void; | ||||||
| 		XModalWindow, | 	(e: 'closed'): void; | ||||||
| 	}, | }>(); | ||||||
| 
 | 
 | ||||||
| 	props: { | let username = $ref(''); | ||||||
| 	}, | let host = $ref(''); | ||||||
|  | let users: misskey.entities.UserDetailed[] = $ref([]); | ||||||
|  | let recentUsers: misskey.entities.UserDetailed[] = $ref([]); | ||||||
|  | let selected: misskey.entities.UserDetailed | null = $ref(null); | ||||||
|  | let usernameEl: HTMLElement = $ref(); | ||||||
|  | let dialogEl = $ref(); | ||||||
| 
 | 
 | ||||||
| 	emits: ['ok', 'cancel', 'closed'], | const focus = () => { | ||||||
| 
 | 	if (usernameEl) { | ||||||
| 	data() { | 		usernameEl.focus(); | ||||||
| 		return { |  | ||||||
| 			username: '', |  | ||||||
| 			host: '', |  | ||||||
| 			recentUsers: [], |  | ||||||
| 			users: [], |  | ||||||
| 			selected: null, |  | ||||||
| 		}; |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	async mounted() { |  | ||||||
| 		this.focus(); |  | ||||||
| 
 |  | ||||||
| 		this.$nextTick(() => { |  | ||||||
| 			this.focus(); |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		this.recentUsers = await os.api('users/show', { |  | ||||||
| 			userIds: this.$store.state.recentlyUsedUsers |  | ||||||
| 		}); |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	methods: { |  | ||||||
| 		search() { |  | ||||||
| 			if (this.username == '' && this.host == '') { |  | ||||||
| 				this.users = []; |  | ||||||
| 				return; |  | ||||||
| 			} |  | ||||||
| 			os.api('users/search-by-username-and-host', { |  | ||||||
| 				username: this.username, |  | ||||||
| 				host: this.host, |  | ||||||
| 				limit: 10, |  | ||||||
| 				detail: false |  | ||||||
| 			}).then(users => { |  | ||||||
| 				this.users = users; |  | ||||||
| 			}); |  | ||||||
| 		}, |  | ||||||
| 
 |  | ||||||
| 		focus() { |  | ||||||
| 			this.$refs.username.focus(); |  | ||||||
| 		}, |  | ||||||
| 
 |  | ||||||
| 		ok() { |  | ||||||
| 			this.$emit('ok', this.selected); |  | ||||||
| 			this.$refs.dialog.close(); |  | ||||||
| 
 |  | ||||||
| 			// 最近使ったユーザー更新 |  | ||||||
| 			let recents = this.$store.state.recentlyUsedUsers; |  | ||||||
| 			recents = recents.filter(x => x !== this.selected.id); |  | ||||||
| 			recents.unshift(this.selected.id); |  | ||||||
| 			this.$store.set('recentlyUsedUsers', recents.splice(0, 16)); |  | ||||||
| 		}, |  | ||||||
| 
 |  | ||||||
| 		cancel() { |  | ||||||
| 			this.$emit('cancel'); |  | ||||||
| 			this.$refs.dialog.close(); |  | ||||||
| 		}, |  | ||||||
| 	} | 	} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const search = () => { | ||||||
|  | 	if (username === '' && host === '') { | ||||||
|  | 		users = []; | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	os.api('users/search-by-username-and-host', { | ||||||
|  | 		username: username, | ||||||
|  | 		host: host, | ||||||
|  | 		limit: 10, | ||||||
|  | 		detail: false | ||||||
|  | 	}).then(_users => { | ||||||
|  | 		users = _users; | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const ok = () => { | ||||||
|  | 	if (selected == null) return; | ||||||
|  | 	emit('ok', selected); | ||||||
|  | 	dialogEl.close(); | ||||||
|  | 
 | ||||||
|  | 	// 最近使ったユーザー更新 | ||||||
|  | 	let recents = defaultStore.state.recentlyUsedUsers; | ||||||
|  | 	recents = recents.filter(x => x !== selected.id); | ||||||
|  | 	recents.unshift(selected.id); | ||||||
|  | 	defaultStore.set('recentlyUsedUsers', recents.splice(0, 16)); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const cancel = () => { | ||||||
|  | 	emit('cancel'); | ||||||
|  | 	dialogEl.close(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | onMounted(() => { | ||||||
|  | 	focus(); | ||||||
|  | 
 | ||||||
|  | 	nextTick(() => { | ||||||
|  | 		focus(); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	os.api('users/show', { | ||||||
|  | 		userIds: defaultStore.state.recentlyUsedUsers, | ||||||
|  | 	}).then(users => { | ||||||
|  | 		recentUsers = users; | ||||||
|  | 	}); | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
| .tbhwbxda { | .tbhwbxda { | ||||||
| 	> ._section { | 	> .form { | ||||||
|  | 		padding: 0 var(--root-margin); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	> .result, > .recent { | ||||||
| 		display: flex; | 		display: flex; | ||||||
| 		flex-direction: column; | 		flex-direction: column; | ||||||
| 		overflow: auto; | 		overflow: auto; | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ | ||||||
| 		</FormSection> | 		</FormSection> | ||||||
| 
 | 
 | ||||||
| 		<FormSection> | 		<FormSection> | ||||||
| 			<div class="_inputSplit _formBlock"> | 			<FormSplit> | ||||||
| 				<MkKeyValue class="_formBlock"> | 				<MkKeyValue class="_formBlock"> | ||||||
| 					<template #key>{{ $ts.administrator }}</template> | 					<template #key>{{ $ts.administrator }}</template> | ||||||
| 					<template #value>{{ $instance.maintainerName }}</template> | 					<template #value>{{ $instance.maintainerName }}</template> | ||||||
|  | @ -33,14 +33,14 @@ | ||||||
| 					<template #key>{{ $ts.contact }}</template> | 					<template #key>{{ $ts.contact }}</template> | ||||||
| 					<template #value>{{ $instance.maintainerEmail }}</template> | 					<template #value>{{ $instance.maintainerEmail }}</template> | ||||||
| 				</MkKeyValue> | 				</MkKeyValue> | ||||||
| 			</div> | 			</FormSplit> | ||||||
| 			<FormLink v-if="$instance.tosUrl" :to="$instance.tosUrl" class="_formBlock" external>{{ $ts.tos }}</FormLink> | 			<FormLink v-if="$instance.tosUrl" :to="$instance.tosUrl" class="_formBlock" external>{{ $ts.tos }}</FormLink> | ||||||
| 		</FormSection> | 		</FormSection> | ||||||
| 
 | 
 | ||||||
| 		<FormSuspense :p="initStats"> | 		<FormSuspense :p="initStats"> | ||||||
| 			<FormSection> | 			<FormSection> | ||||||
| 				<template #label>{{ $ts.statistics }}</template> | 				<template #label>{{ $ts.statistics }}</template> | ||||||
| 				<div class="_inputSplit"> | 				<FormSplit> | ||||||
| 					<MkKeyValue class="_formBlock"> | 					<MkKeyValue class="_formBlock"> | ||||||
| 						<template #key>{{ $ts.users }}</template> | 						<template #key>{{ $ts.users }}</template> | ||||||
| 						<template #value>{{ number(stats.originalUsersCount) }}</template> | 						<template #value>{{ number(stats.originalUsersCount) }}</template> | ||||||
|  | @ -49,7 +49,7 @@ | ||||||
| 						<template #key>{{ $ts.notes }}</template> | 						<template #key>{{ $ts.notes }}</template> | ||||||
| 						<template #value>{{ number(stats.originalNotesCount) }}</template> | 						<template #value>{{ number(stats.originalNotesCount) }}</template> | ||||||
| 					</MkKeyValue> | 					</MkKeyValue> | ||||||
| 				</div> | 				</FormSplit> | ||||||
| 			</FormSection> | 			</FormSection> | ||||||
| 		</FormSuspense> | 		</FormSuspense> | ||||||
| 
 | 
 | ||||||
|  | @ -73,6 +73,7 @@ import { version, instanceName } from '@/config'; | ||||||
| import FormLink from '@/components/form/link.vue'; | import FormLink from '@/components/form/link.vue'; | ||||||
| import FormSection from '@/components/form/section.vue'; | import FormSection from '@/components/form/section.vue'; | ||||||
| import FormSuspense from '@/components/form/suspense.vue'; | import FormSuspense from '@/components/form/suspense.vue'; | ||||||
|  | import FormSplit from '@/components/form/split.vue'; | ||||||
| import MkKeyValue from '@/components/key-value.vue'; | import MkKeyValue from '@/components/key-value.vue'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import number from '@/filters/number'; | import number from '@/filters/number'; | ||||||
|  | @ -85,6 +86,7 @@ export default defineComponent({ | ||||||
| 		FormSection, | 		FormSection, | ||||||
| 		FormLink, | 		FormLink, | ||||||
| 		FormSuspense, | 		FormSuspense, | ||||||
|  | 		FormSplit, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	data() { | 	data() { | ||||||
|  |  | ||||||
|  | @ -23,14 +23,14 @@ | ||||||
| 				<MkRadio v-model="ad.priority" value="low">{{ $ts.low }}</MkRadio> | 				<MkRadio v-model="ad.priority" value="low">{{ $ts.low }}</MkRadio> | ||||||
| 			</div> | 			</div> | ||||||
| 			--> | 			--> | ||||||
| 			<div class="_inputSplit"> | 			<FormSplit> | ||||||
| 				<MkInput v-model="ad.ratio" type="number"> | 				<MkInput v-model="ad.ratio" type="number"> | ||||||
| 					<template #label>{{ $ts.ratio }}</template> | 					<template #label>{{ $ts.ratio }}</template> | ||||||
| 				</MkInput> | 				</MkInput> | ||||||
| 				<MkInput v-model="ad.expiresAt" type="date"> | 				<MkInput v-model="ad.expiresAt" type="date"> | ||||||
| 					<template #label>{{ $ts.expiration }}</template> | 					<template #label>{{ $ts.expiration }}</template> | ||||||
| 				</MkInput> | 				</MkInput> | ||||||
| 			</div> | 			</FormSplit> | ||||||
| 			<MkTextarea v-model="ad.memo" class="_formBlock"> | 			<MkTextarea v-model="ad.memo" class="_formBlock"> | ||||||
| 				<template #label>{{ $ts.memo }}</template> | 				<template #label>{{ $ts.memo }}</template> | ||||||
| 			</MkTextarea> | 			</MkTextarea> | ||||||
|  | @ -49,6 +49,7 @@ import MkButton from '@/components/ui/button.vue'; | ||||||
| import MkInput from '@/components/form/input.vue'; | import MkInput from '@/components/form/input.vue'; | ||||||
| import MkTextarea from '@/components/form/textarea.vue'; | import MkTextarea from '@/components/form/textarea.vue'; | ||||||
| import FormRadios from '@/components/form/radios.vue'; | import FormRadios from '@/components/form/radios.vue'; | ||||||
|  | import FormSplit from '@/components/form/split.vue'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import * as symbols from '@/symbols'; | import * as symbols from '@/symbols'; | ||||||
| 
 | 
 | ||||||
|  | @ -58,6 +59,7 @@ export default defineComponent({ | ||||||
| 		MkInput, | 		MkInput, | ||||||
| 		MkTextarea, | 		MkTextarea, | ||||||
| 		FormRadios, | 		FormRadios, | ||||||
|  | 		FormSplit, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	emits: ['info'], | 	emits: ['info'], | ||||||
|  |  | ||||||
|  | @ -1,50 +1,55 @@ | ||||||
| <template> | <template> | ||||||
| <FormBase> | <MkSpacer :content-max="700" :margin-min="16" :margin-max="32"> | ||||||
| 	<FormSuspense :p="init"> | 	<FormSuspense :p="init"> | ||||||
| 		<FormSwitch v-model="enableEmail">{{ $ts.enableEmail }}<template #desc>{{ $ts.emailConfigInfo }}</template></FormSwitch> | 		<div class="_formRoot"> | ||||||
|  | 			<FormSwitch v-model="enableEmail" class="_formBlock"> | ||||||
|  | 				<template #label>{{ $ts.enableEmail }}</template> | ||||||
|  | 				<template #caption>{{ $ts.emailConfigInfo }}</template> | ||||||
|  | 			</FormSwitch> | ||||||
| 
 | 
 | ||||||
| 		<template v-if="enableEmail"> | 			<template v-if="enableEmail"> | ||||||
| 			<FormInput v-model="email" type="email"> | 				<FormInput v-model="email" type="email" class="_formBlock"> | ||||||
| 				<span>{{ $ts.emailAddress }}</span> | 					<template #label>{{ $ts.emailAddress }}</template> | ||||||
| 			</FormInput> | 				</FormInput> | ||||||
| 
 | 
 | ||||||
| 			<div v-sticky-container class="_debobigegoItem _debobigegoNoConcat"> | 				<FormSection> | ||||||
| 				<div class="_debobigegoLabel">{{ $ts.smtpConfig }}</div> | 					<template #label>{{ $ts.smtpConfig }}</template> | ||||||
| 				<div class="main"> | 					<FormSplit :min-width="280"> | ||||||
| 					<FormInput v-model="smtpHost"> | 						<FormInput v-model="smtpHost" class="_formBlock"> | ||||||
| 						<span>{{ $ts.smtpHost }}</span> | 							<template #label>{{ $ts.smtpHost }}</template> | ||||||
| 					</FormInput> | 						</FormInput> | ||||||
| 					<FormInput v-model="smtpPort" type="number"> | 						<FormInput v-model="smtpPort" type="number" class="_formBlock"> | ||||||
| 						<span>{{ $ts.smtpPort }}</span> | 							<template #label>{{ $ts.smtpPort }}</template> | ||||||
| 					</FormInput> | 						</FormInput> | ||||||
| 					<FormInput v-model="smtpUser"> | 					</FormSplit> | ||||||
| 						<span>{{ $ts.smtpUser }}</span> | 					<FormSplit :min-width="280"> | ||||||
| 					</FormInput> | 						<FormInput v-model="smtpUser" class="_formBlock"> | ||||||
| 					<FormInput v-model="smtpPass" type="password"> | 							<template #label>{{ $ts.smtpUser }}</template> | ||||||
| 						<span>{{ $ts.smtpPass }}</span> | 						</FormInput> | ||||||
| 					</FormInput> | 						<FormInput v-model="smtpPass" type="password" class="_formBlock"> | ||||||
| 					<FormInfo>{{ $ts.emptyToDisableSmtpAuth }}</FormInfo> | 							<template #label>{{ $ts.smtpPass }}</template> | ||||||
| 					<FormSwitch v-model="smtpSecure">{{ $ts.smtpSecure }}<template #desc>{{ $ts.smtpSecureInfo }}</template></FormSwitch> | 						</FormInput> | ||||||
| 				</div> | 					</FormSplit> | ||||||
| 			</div> | 					<FormInfo class="_formBlock">{{ $ts.emptyToDisableSmtpAuth }}</FormInfo> | ||||||
| 
 | 					<FormSwitch v-model="smtpSecure" class="_formBlock"> | ||||||
| 			<FormButton @click="testEmail">{{ $ts.testEmail }}</FormButton> | 						<template #label>{{ $ts.smtpSecure }}</template> | ||||||
| 		</template> | 						<template #caption>{{ $ts.smtpSecureInfo }}</template> | ||||||
| 
 | 					</FormSwitch> | ||||||
| 		<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> | 				</FormSection> | ||||||
|  | 			</template> | ||||||
|  | 		</div> | ||||||
| 	</FormSuspense> | 	</FormSuspense> | ||||||
| </FormBase> | </MkSpacer> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent } from 'vue'; | import { defineComponent } from 'vue'; | ||||||
| import FormSwitch from '@/components/debobigego/switch.vue'; | import FormSwitch from '@/components/form/switch.vue'; | ||||||
| import FormInput from '@/components/debobigego/input.vue'; | import FormInput from '@/components/form/input.vue'; | ||||||
| import FormButton from '@/components/debobigego/button.vue'; | import FormInfo from '@/components/ui/info.vue'; | ||||||
| import FormBase from '@/components/debobigego/base.vue'; | import FormSuspense from '@/components/form/suspense.vue'; | ||||||
| import FormGroup from '@/components/debobigego/group.vue'; | import FormSplit from '@/components/form/split.vue'; | ||||||
| import FormInfo from '@/components/debobigego/info.vue'; | import FormSection from '@/components/form/section.vue'; | ||||||
| import FormSuspense from '@/components/debobigego/suspense.vue'; |  | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import * as symbols from '@/symbols'; | import * as symbols from '@/symbols'; | ||||||
| import { fetchInstance } from '@/instance'; | import { fetchInstance } from '@/instance'; | ||||||
|  | @ -53,9 +58,8 @@ export default defineComponent({ | ||||||
| 	components: { | 	components: { | ||||||
| 		FormSwitch, | 		FormSwitch, | ||||||
| 		FormInput, | 		FormInput, | ||||||
| 		FormBase, | 		FormSplit, | ||||||
| 		FormGroup, | 		FormSection, | ||||||
| 		FormButton, |  | ||||||
| 		FormInfo, | 		FormInfo, | ||||||
| 		FormSuspense, | 		FormSuspense, | ||||||
| 	}, | 	}, | ||||||
|  | @ -68,6 +72,16 @@ export default defineComponent({ | ||||||
| 				title: this.$ts.emailServer, | 				title: this.$ts.emailServer, | ||||||
| 				icon: 'fas fa-envelope', | 				icon: 'fas fa-envelope', | ||||||
| 				bg: 'var(--bg)', | 				bg: 'var(--bg)', | ||||||
|  | 				actions: [{ | ||||||
|  | 					asFullButton: true, | ||||||
|  | 					text: this.$ts.testEmail, | ||||||
|  | 					handler: this.testEmail, | ||||||
|  | 				}, { | ||||||
|  | 					asFullButton: true, | ||||||
|  | 					icon: 'fas fa-check', | ||||||
|  | 					text: this.$ts.save, | ||||||
|  | 					handler: this.save, | ||||||
|  | 				}], | ||||||
| 			}, | 			}, | ||||||
| 			enableEmail: false, | 			enableEmail: false, | ||||||
| 			email: null, | 			email: null, | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ | ||||||
| 		</div> | 		</div> | ||||||
| 
 | 
 | ||||||
| 		<div v-else-if="tab === 'remote'" class="remote"> | 		<div v-else-if="tab === 'remote'" class="remote"> | ||||||
| 			<div class="_inputSplit"> | 			<FormSplit> | ||||||
| 				<MkInput v-model="queryRemote" :debounce="true" type="search"> | 				<MkInput v-model="queryRemote" :debounce="true" type="search"> | ||||||
| 					<template #prefix><i class="fas fa-search"></i></template> | 					<template #prefix><i class="fas fa-search"></i></template> | ||||||
| 					<template #label>{{ $ts.search }}</template> | 					<template #label>{{ $ts.search }}</template> | ||||||
|  | @ -31,7 +31,7 @@ | ||||||
| 				<MkInput v-model="host" :debounce="true"> | 				<MkInput v-model="host" :debounce="true"> | ||||||
| 					<template #label>{{ $ts.host }}</template> | 					<template #label>{{ $ts.host }}</template> | ||||||
| 				</MkInput> | 				</MkInput> | ||||||
| 			</div> | 			</FormSplit> | ||||||
| 			<MkPagination ref="remoteEmojis" :pagination="remotePagination"> | 			<MkPagination ref="remoteEmojis" :pagination="remotePagination"> | ||||||
| 				<template #empty><span>{{ $ts.noCustomEmojis }}</span></template> | 				<template #empty><span>{{ $ts.noCustomEmojis }}</span></template> | ||||||
| 				<template v-slot="{items}"> | 				<template v-slot="{items}"> | ||||||
|  | @ -57,6 +57,7 @@ import MkButton from '@/components/ui/button.vue'; | ||||||
| import MkInput from '@/components/form/input.vue'; | import MkInput from '@/components/form/input.vue'; | ||||||
| import MkPagination from '@/components/ui/pagination.vue'; | import MkPagination from '@/components/ui/pagination.vue'; | ||||||
| import MkTab from '@/components/tab.vue'; | import MkTab from '@/components/tab.vue'; | ||||||
|  | import FormSplit from '@/components/form/split.vue'; | ||||||
| import { selectFiles } from '@/scripts/select-file'; | import { selectFiles } from '@/scripts/select-file'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import * as symbols from '@/symbols'; | import * as symbols from '@/symbols'; | ||||||
|  | @ -67,6 +68,7 @@ export default defineComponent({ | ||||||
| 		MkButton, | 		MkButton, | ||||||
| 		MkInput, | 		MkInput, | ||||||
| 		MkPagination, | 		MkPagination, | ||||||
|  | 		FormSplit, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	emits: ['info'], | 	emits: ['info'], | ||||||
|  |  | ||||||
|  | @ -1,41 +1,41 @@ | ||||||
| <template> | <template> | ||||||
| <FormBase> | <MkSpacer :content-max="700" :margin-min="16" :margin-max="32"> | ||||||
| 	<FormSuspense :p="init"> | 	<FormSuspense :p="init"> | ||||||
| 		<FormSwitch v-model="cacheRemoteFiles"> | 		<div class="_formRoot"> | ||||||
| 			{{ $ts.cacheRemoteFiles }} | 			<FormSwitch v-model="cacheRemoteFiles" class="_formBlock"> | ||||||
| 			<template #desc>{{ $ts.cacheRemoteFilesDescription }}</template> | 				<template #label>{{ $ts.cacheRemoteFiles }}</template> | ||||||
| 		</FormSwitch> | 				<template #caption>{{ $ts.cacheRemoteFilesDescription }}</template> | ||||||
|  | 			</FormSwitch> | ||||||
| 
 | 
 | ||||||
| 		<FormSwitch v-model="proxyRemoteFiles"> | 			<FormSwitch v-model="proxyRemoteFiles" class="_formBlock"> | ||||||
| 			{{ $ts.proxyRemoteFiles }} | 				<template #label>{{ $ts.proxyRemoteFiles }}</template> | ||||||
| 			<template #desc>{{ $ts.proxyRemoteFilesDescription }}</template> | 				<template #caption>{{ $ts.proxyRemoteFilesDescription }}</template> | ||||||
| 		</FormSwitch> | 			</FormSwitch> | ||||||
| 
 | 
 | ||||||
| 		<FormInput v-model="localDriveCapacityMb" type="number"> | 			<FormSplit :min-width="280"> | ||||||
| 			<span>{{ $ts.driveCapacityPerLocalAccount }}</span> | 				<FormInput v-model="localDriveCapacityMb" type="number" class="_formBlock"> | ||||||
| 			<template #suffix>MB</template> | 					<template #label>{{ $ts.driveCapacityPerLocalAccount }}</template> | ||||||
| 			<template #desc>{{ $ts.inMb }}</template> | 					<template #suffix>MB</template> | ||||||
| 		</FormInput> | 					<template #caption>{{ $ts.inMb }}</template> | ||||||
|  | 				</FormInput> | ||||||
| 
 | 
 | ||||||
| 		<FormInput v-model="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles"> | 				<FormInput v-model="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles" class="_formBlock"> | ||||||
| 			<span>{{ $ts.driveCapacityPerRemoteAccount }}</span> | 					<template #label>{{ $ts.driveCapacityPerRemoteAccount }}</template> | ||||||
| 			<template #suffix>MB</template> | 					<template #suffix>MB</template> | ||||||
| 			<template #desc>{{ $ts.inMb }}</template> | 					<template #caption>{{ $ts.inMb }}</template> | ||||||
| 		</FormInput> | 				</FormInput> | ||||||
| 
 | 			</FormSplit> | ||||||
| 		<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> | 		</div> | ||||||
| 	</FormSuspense> | 	</FormSuspense> | ||||||
| </FormBase> | </MkSpacer> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent } from 'vue'; | import { defineComponent } from 'vue'; | ||||||
| import FormSwitch from '@/components/debobigego/switch.vue'; | import FormSwitch from '@/components/form/switch.vue'; | ||||||
| import FormInput from '@/components/debobigego/input.vue'; | import FormInput from '@/components/form/input.vue'; | ||||||
| import FormButton from '@/components/debobigego/button.vue'; | import FormSuspense from '@/components/form/suspense.vue'; | ||||||
| import FormBase from '@/components/debobigego/base.vue'; | import FormSplit from '@/components/form/split.vue'; | ||||||
| import FormGroup from '@/components/debobigego/group.vue'; |  | ||||||
| import FormSuspense from '@/components/debobigego/suspense.vue'; |  | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import * as symbols from '@/symbols'; | import * as symbols from '@/symbols'; | ||||||
| import { fetchInstance } from '@/instance'; | import { fetchInstance } from '@/instance'; | ||||||
|  | @ -44,9 +44,7 @@ export default defineComponent({ | ||||||
| 	components: { | 	components: { | ||||||
| 		FormSwitch, | 		FormSwitch, | ||||||
| 		FormInput, | 		FormInput, | ||||||
| 		FormBase, | 		FormSplit, | ||||||
| 		FormGroup, |  | ||||||
| 		FormButton, |  | ||||||
| 		FormSuspense, | 		FormSuspense, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | @ -58,6 +56,12 @@ export default defineComponent({ | ||||||
| 				title: this.$ts.files, | 				title: this.$ts.files, | ||||||
| 				icon: 'fas fa-cloud', | 				icon: 'fas fa-cloud', | ||||||
| 				bg: 'var(--bg)', | 				bg: 'var(--bg)', | ||||||
|  | 				actions: [{ | ||||||
|  | 					asFullButton: true, | ||||||
|  | 					icon: 'fas fa-check', | ||||||
|  | 					text: this.$ts.save, | ||||||
|  | 					handler: this.save, | ||||||
|  | 				}], | ||||||
| 			}, | 			}, | ||||||
| 			cacheRemoteFiles: false, | 			cacheRemoteFiles: false, | ||||||
| 			proxyRemoteFiles: false, | 			proxyRemoteFiles: false, | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
| 	<div v-if="!narrow || page == null" class="nav"> | 	<div v-if="!narrow || page == null" class="nav"> | ||||||
| 		<MkHeader :info="header"></MkHeader> | 		<MkHeader :info="header"></MkHeader> | ||||||
| 	 | 	 | ||||||
| 		<MkSpacer :content-max="700"> | 		<MkSpacer :content-max="700" :margin-min="16"> | ||||||
| 			<div class="lxpfedzu"> | 			<div class="lxpfedzu"> | ||||||
| 				<div class="banner"> | 				<div class="banner"> | ||||||
| 					<img :src="$instance.iconUrl || '/favicon.ico'" alt="" class="icon"/> | 					<img :src="$instance.iconUrl || '/favicon.ico'" alt="" class="icon"/> | ||||||
|  |  | ||||||
|  | @ -1,76 +1,78 @@ | ||||||
| <template> | <template> | ||||||
| <FormBase> | <MkSpacer :content-max="700" :margin-min="16" :margin-max="32"> | ||||||
| 	<FormSuspense :p="init"> | 	<FormSuspense :p="init"> | ||||||
| 		<FormSwitch v-model="useObjectStorage">{{ $ts.useObjectStorage }}</FormSwitch> | 		<div class="_formRoot"> | ||||||
|  | 			<FormSwitch v-model="useObjectStorage" class="_formBlock">{{ $ts.useObjectStorage }}</FormSwitch> | ||||||
| 
 | 
 | ||||||
| 		<template v-if="useObjectStorage"> | 			<template v-if="useObjectStorage"> | ||||||
| 			<FormInput v-model="objectStorageBaseUrl"> | 				<FormInput v-model="objectStorageBaseUrl" class="_formBlock"> | ||||||
| 				<span>{{ $ts.objectStorageBaseUrl }}</span> | 					<template #label>{{ $ts.objectStorageBaseUrl }}</template> | ||||||
| 				<template #desc>{{ $ts.objectStorageBaseUrlDesc }}</template> | 					<template #caption>{{ $ts.objectStorageBaseUrlDesc }}</template> | ||||||
| 			</FormInput> | 				</FormInput> | ||||||
| 
 | 
 | ||||||
| 			<FormInput v-model="objectStorageBucket"> | 				<FormInput v-model="objectStorageBucket" class="_formBlock"> | ||||||
| 				<span>{{ $ts.objectStorageBucket }}</span> | 					<template #label>{{ $ts.objectStorageBucket }}</template> | ||||||
| 				<template #desc>{{ $ts.objectStorageBucketDesc }}</template> | 					<template #caption>{{ $ts.objectStorageBucketDesc }}</template> | ||||||
| 			</FormInput> | 				</FormInput> | ||||||
| 
 | 
 | ||||||
| 			<FormInput v-model="objectStoragePrefix"> | 				<FormInput v-model="objectStoragePrefix" class="_formBlock"> | ||||||
| 				<span>{{ $ts.objectStoragePrefix }}</span> | 					<template #label>{{ $ts.objectStoragePrefix }}</template> | ||||||
| 				<template #desc>{{ $ts.objectStoragePrefixDesc }}</template> | 					<template #caption>{{ $ts.objectStoragePrefixDesc }}</template> | ||||||
| 			</FormInput> | 				</FormInput> | ||||||
| 
 | 
 | ||||||
| 			<FormInput v-model="objectStorageEndpoint"> | 				<FormInput v-model="objectStorageEndpoint" class="_formBlock"> | ||||||
| 				<span>{{ $ts.objectStorageEndpoint }}</span> | 					<template #label>{{ $ts.objectStorageEndpoint }}</template> | ||||||
| 				<template #desc>{{ $ts.objectStorageEndpointDesc }}</template> | 					<template #caption>{{ $ts.objectStorageEndpointDesc }}</template> | ||||||
| 			</FormInput> | 				</FormInput> | ||||||
| 
 | 
 | ||||||
| 			<FormInput v-model="objectStorageRegion"> | 				<FormInput v-model="objectStorageRegion" class="_formBlock"> | ||||||
| 				<span>{{ $ts.objectStorageRegion }}</span> | 					<template #label>{{ $ts.objectStorageRegion }}</template> | ||||||
| 				<template #desc>{{ $ts.objectStorageRegionDesc }}</template> | 					<template #caption>{{ $ts.objectStorageRegionDesc }}</template> | ||||||
| 			</FormInput> | 				</FormInput> | ||||||
| 
 | 
 | ||||||
| 			<FormInput v-model="objectStorageAccessKey"> | 				<FormSplit :min-width="280"> | ||||||
| 				<template #prefix><i class="fas fa-key"></i></template> | 					<FormInput v-model="objectStorageAccessKey" class="_formBlock"> | ||||||
| 				<span>Access key</span> | 						<template #prefix><i class="fas fa-key"></i></template> | ||||||
| 			</FormInput> | 						<template #label>Access key</template> | ||||||
|  | 					</FormInput> | ||||||
| 
 | 
 | ||||||
| 			<FormInput v-model="objectStorageSecretKey"> | 					<FormInput v-model="objectStorageSecretKey" class="_formBlock"> | ||||||
| 				<template #prefix><i class="fas fa-key"></i></template> | 						<template #prefix><i class="fas fa-key"></i></template> | ||||||
| 				<span>Secret key</span> | 						<template #label>Secret key</template> | ||||||
| 			</FormInput> | 					</FormInput> | ||||||
|  | 				</FormSplit> | ||||||
| 
 | 
 | ||||||
| 			<FormSwitch v-model="objectStorageUseSSL"> | 				<FormSwitch v-model="objectStorageUseSSL" class="_formBlock"> | ||||||
| 				{{ $ts.objectStorageUseSSL }} | 					<template #label>{{ $ts.objectStorageUseSSL }}</template> | ||||||
| 				<template #desc>{{ $ts.objectStorageUseSSLDesc }}</template> | 					<template #caption>{{ $ts.objectStorageUseSSLDesc }}</template> | ||||||
| 			</FormSwitch> | 				</FormSwitch> | ||||||
| 
 | 
 | ||||||
| 			<FormSwitch v-model="objectStorageUseProxy"> | 				<FormSwitch v-model="objectStorageUseProxy" class="_formBlock"> | ||||||
| 				{{ $ts.objectStorageUseProxy }} | 					<template #label>{{ $ts.objectStorageUseProxy }}</template> | ||||||
| 				<template #desc>{{ $ts.objectStorageUseProxyDesc }}</template> | 					<template #caption>{{ $ts.objectStorageUseProxyDesc }}</template> | ||||||
| 			</FormSwitch> | 				</FormSwitch> | ||||||
| 
 | 
 | ||||||
| 			<FormSwitch v-model="objectStorageSetPublicRead"> | 				<FormSwitch v-model="objectStorageSetPublicRead" class="_formBlock"> | ||||||
| 				{{ $ts.objectStorageSetPublicRead }} | 					<template #label>{{ $ts.objectStorageSetPublicRead }}</template> | ||||||
| 			</FormSwitch> | 				</FormSwitch> | ||||||
| 
 | 
 | ||||||
| 			<FormSwitch v-model="objectStorageS3ForcePathStyle"> | 				<FormSwitch v-model="objectStorageS3ForcePathStyle" class="_formBlock"> | ||||||
| 				s3ForcePathStyle | 					<template #label>s3ForcePathStyle</template> | ||||||
| 			</FormSwitch> | 				</FormSwitch> | ||||||
| 		</template> | 			</template> | ||||||
| 
 | 		</div> | ||||||
| 		<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> |  | ||||||
| 	</FormSuspense> | 	</FormSuspense> | ||||||
| </FormBase> | </MkSpacer> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent } from 'vue'; | import { defineComponent } from 'vue'; | ||||||
| import FormSwitch from '@/components/debobigego/switch.vue'; | import FormSwitch from '@/components/form/switch.vue'; | ||||||
| import FormInput from '@/components/debobigego/input.vue'; | import FormInput from '@/components/form/input.vue'; | ||||||
| import FormButton from '@/components/debobigego/button.vue'; | import FormGroup from '@/components/form/group.vue'; | ||||||
| import FormBase from '@/components/debobigego/base.vue'; | import FormSuspense from '@/components/form/suspense.vue'; | ||||||
| import FormGroup from '@/components/debobigego/group.vue'; | import FormSplit from '@/components/form/split.vue'; | ||||||
| import FormSuspense from '@/components/debobigego/suspense.vue'; | import FormSection from '@/components/form/section.vue'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import * as symbols from '@/symbols'; | import * as symbols from '@/symbols'; | ||||||
| import { fetchInstance } from '@/instance'; | import { fetchInstance } from '@/instance'; | ||||||
|  | @ -79,10 +81,10 @@ export default defineComponent({ | ||||||
| 	components: { | 	components: { | ||||||
| 		FormSwitch, | 		FormSwitch, | ||||||
| 		FormInput, | 		FormInput, | ||||||
| 		FormBase, |  | ||||||
| 		FormGroup, | 		FormGroup, | ||||||
| 		FormButton, |  | ||||||
| 		FormSuspense, | 		FormSuspense, | ||||||
|  | 		FormSplit, | ||||||
|  | 		FormSection, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	emits: ['info'], | 	emits: ['info'], | ||||||
|  | @ -93,6 +95,12 @@ export default defineComponent({ | ||||||
| 				title: this.$ts.objectStorage, | 				title: this.$ts.objectStorage, | ||||||
| 				icon: 'fas fa-cloud', | 				icon: 'fas fa-cloud', | ||||||
| 				bg: 'var(--bg)', | 				bg: 'var(--bg)', | ||||||
|  | 				actions: [{ | ||||||
|  | 					asFullButton: true, | ||||||
|  | 					icon: 'fas fa-check', | ||||||
|  | 					text: this.$ts.save, | ||||||
|  | 					handler: this.save, | ||||||
|  | 				}], | ||||||
| 			}, | 			}, | ||||||
| 			useObjectStorage: false, | 			useObjectStorage: false, | ||||||
| 			objectStorageBaseUrl: null, | 			objectStorageBaseUrl: null, | ||||||
|  |  | ||||||
|  | @ -1,31 +1,35 @@ | ||||||
| <template> | <template> | ||||||
| <FormBase> | <MkSpacer :content-max="700" :margin-min="16" :margin-max="32"> | ||||||
| 	<FormSuspense :p="init"> | 	<FormSuspense :p="init"> | ||||||
| 		<FormLink to="/admin/bot-protection"> | 		<div class="_formRoot"> | ||||||
| 			<i class="fas fa-shield-alt"></i> {{ $ts.botProtection }} | 			<FormSection> | ||||||
| 			<template v-if="enableHcaptcha" #suffix>hCaptcha</template> | 				<FormSwitch v-model="enableRegistration" class="_formBlock"> | ||||||
| 			<template v-else-if="enableRecaptcha" #suffix>reCAPTCHA</template> | 					<template #label>{{ $ts.enableRegistration }}</template> | ||||||
| 			<template v-else #suffix>{{ $ts.none }} ({{ $ts.notRecommended }})</template> | 				</FormSwitch> | ||||||
| 		</FormLink> |  | ||||||
| 
 | 
 | ||||||
| 		<FormSwitch v-model="enableRegistration">{{ $ts.enableRegistration }}</FormSwitch> | 				<FormSwitch v-model="emailRequiredForSignup" class="_formBlock"> | ||||||
|  | 					<template #label>{{ $ts.emailRequiredForSignup }}</template> | ||||||
|  | 				</FormSwitch> | ||||||
|  | 			</FormSection> | ||||||
| 
 | 
 | ||||||
| 		<FormSwitch v-model="emailRequiredForSignup">{{ $ts.emailRequiredForSignup }}</FormSwitch> | 			<FormLink to="/admin/bot-protection" class="_formBlock"> | ||||||
| 
 | 				<i class="fas fa-shield-alt"></i> {{ $ts.botProtection }} | ||||||
| 		<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> | 				<template v-if="enableHcaptcha" #suffix>hCaptcha</template> | ||||||
|  | 				<template v-else-if="enableRecaptcha" #suffix>reCAPTCHA</template> | ||||||
|  | 				<template v-else #suffix>{{ $ts.none }} ({{ $ts.notRecommended }})</template> | ||||||
|  | 			</FormLink> | ||||||
|  | 		</div> | ||||||
| 	</FormSuspense> | 	</FormSuspense> | ||||||
| </FormBase> | </MkSpacer> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineAsyncComponent, defineComponent } from 'vue'; | import { defineAsyncComponent, defineComponent } from 'vue'; | ||||||
| import FormLink from '@/components/debobigego/link.vue'; | import FormLink from '@/components/form/link.vue'; | ||||||
| import FormSwitch from '@/components/debobigego/switch.vue'; | import FormSwitch from '@/components/form/switch.vue'; | ||||||
| import FormButton from '@/components/debobigego/button.vue'; | import FormInfo from '@/components/ui/info.vue'; | ||||||
| import FormBase from '@/components/debobigego/base.vue'; | import FormSuspense from '@/components/form/suspense.vue'; | ||||||
| import FormGroup from '@/components/debobigego/group.vue'; | import FormSection from '@/components/form/section.vue'; | ||||||
| import FormInfo from '@/components/debobigego/info.vue'; |  | ||||||
| import FormSuspense from '@/components/debobigego/suspense.vue'; |  | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import * as symbols from '@/symbols'; | import * as symbols from '@/symbols'; | ||||||
| import { fetchInstance } from '@/instance'; | import { fetchInstance } from '@/instance'; | ||||||
|  | @ -34,10 +38,8 @@ export default defineComponent({ | ||||||
| 	components: { | 	components: { | ||||||
| 		FormLink, | 		FormLink, | ||||||
| 		FormSwitch, | 		FormSwitch, | ||||||
| 		FormBase, |  | ||||||
| 		FormGroup, |  | ||||||
| 		FormButton, |  | ||||||
| 		FormInfo, | 		FormInfo, | ||||||
|  | 		FormSection, | ||||||
| 		FormSuspense, | 		FormSuspense, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | @ -49,6 +51,12 @@ export default defineComponent({ | ||||||
| 				title: this.$ts.security, | 				title: this.$ts.security, | ||||||
| 				icon: 'fas fa-lock', | 				icon: 'fas fa-lock', | ||||||
| 				bg: 'var(--bg)', | 				bg: 'var(--bg)', | ||||||
|  | 				actions: [{ | ||||||
|  | 					asFullButton: true, | ||||||
|  | 					icon: 'fas fa-check', | ||||||
|  | 					text: this.$ts.save, | ||||||
|  | 					handler: this.save, | ||||||
|  | 				}], | ||||||
| 			}, | 			}, | ||||||
| 			enableHcaptcha: false, | 			enableHcaptcha: false, | ||||||
| 			enableRecaptcha: false, | 			enableRecaptcha: false, | ||||||
|  |  | ||||||
|  | @ -1,72 +1,75 @@ | ||||||
| <template> | <template> | ||||||
| <FormBase> | <MkSpacer :content-max="700" :margin-min="16" :margin-max="32"> | ||||||
| 	<FormSuspense :p="init"> | 	<FormSuspense :p="init"> | ||||||
| 		<FormInput v-model="name"> | 		<div class="_formRoot"> | ||||||
| 			<span>{{ $ts.instanceName }}</span> | 			<FormInput v-model="name" class="_formBlock"> | ||||||
| 		</FormInput> | 				<template #label>{{ $ts.instanceName }}</template> | ||||||
|  | 			</FormInput> | ||||||
| 
 | 
 | ||||||
| 		<FormTextarea v-model="description"> | 			<FormTextarea v-model="description" class="_formBlock"> | ||||||
| 			<span>{{ $ts.instanceDescription }}</span> | 				<template #label>{{ $ts.instanceDescription }}</template> | ||||||
| 		</FormTextarea> | 			</FormTextarea> | ||||||
| 
 | 
 | ||||||
| 		<FormInput v-model="iconUrl"> | 			<FormInput v-model="iconUrl" class="_formBlock"> | ||||||
| 			<template #prefix><i class="fas fa-link"></i></template> | 				<template #prefix><i class="fas fa-link"></i></template> | ||||||
| 			<span>{{ $ts.iconUrl }}</span> | 				<template #label>{{ $ts.iconUrl }}</template> | ||||||
| 		</FormInput> | 			</FormInput> | ||||||
| 
 | 
 | ||||||
| 		<FormInput v-model="bannerUrl"> | 			<FormInput v-model="bannerUrl" class="_formBlock"> | ||||||
| 			<template #prefix><i class="fas fa-link"></i></template> | 				<template #prefix><i class="fas fa-link"></i></template> | ||||||
| 			<span>{{ $ts.bannerUrl }}</span> | 				<template #label>{{ $ts.bannerUrl }}</template> | ||||||
| 		</FormInput> | 			</FormInput> | ||||||
| 
 | 
 | ||||||
| 		<FormInput v-model="backgroundImageUrl"> | 			<FormInput v-model="backgroundImageUrl" class="_formBlock"> | ||||||
| 			<template #prefix><i class="fas fa-link"></i></template> | 				<template #prefix><i class="fas fa-link"></i></template> | ||||||
| 			<span>{{ $ts.backgroundImageUrl }}</span> | 				<template #label>{{ $ts.backgroundImageUrl }}</template> | ||||||
| 		</FormInput> | 			</FormInput> | ||||||
| 
 | 
 | ||||||
| 		<FormInput v-model="tosUrl"> | 			<FormInput v-model="tosUrl" class="_formBlock"> | ||||||
| 			<template #prefix><i class="fas fa-link"></i></template> | 				<template #prefix><i class="fas fa-link"></i></template> | ||||||
| 			<span>{{ $ts.tosUrl }}</span> | 				<template #label>{{ $ts.tosUrl }}</template> | ||||||
| 		</FormInput> | 			</FormInput> | ||||||
| 
 | 
 | ||||||
| 		<FormInput v-model="maintainerName"> | 			<FormSplit :min-width="300"> | ||||||
| 			<span>{{ $ts.maintainerName }}</span> | 				<FormInput v-model="maintainerName" class="_formBlock"> | ||||||
| 		</FormInput> | 					<template #label>{{ $ts.maintainerName }}</template> | ||||||
|  | 				</FormInput> | ||||||
| 
 | 
 | ||||||
| 		<FormInput v-model="maintainerEmail" type="email"> | 				<FormInput v-model="maintainerEmail" type="email" class="_formBlock"> | ||||||
| 			<template #prefix><i class="fas fa-envelope"></i></template> | 					<template #prefix><i class="fas fa-envelope"></i></template> | ||||||
| 			<span>{{ $ts.maintainerEmail }}</span> | 					<template #label>{{ $ts.maintainerEmail }}</template> | ||||||
| 		</FormInput> | 				</FormInput> | ||||||
|  | 			</FormSplit> | ||||||
| 
 | 
 | ||||||
| 		<FormTextarea v-model="pinnedUsers"> | 			<FormTextarea v-model="pinnedUsers" class="_formBlock"> | ||||||
| 			<span>{{ $ts.pinnedUsers }}</span> | 				<template #label>{{ $ts.pinnedUsers }}</template> | ||||||
| 			<template #desc>{{ $ts.pinnedUsersDescription }}</template> | 				<template #caption>{{ $ts.pinnedUsersDescription }}</template> | ||||||
| 		</FormTextarea> | 			</FormTextarea> | ||||||
| 
 | 
 | ||||||
| 		<FormInput v-model="maxNoteTextLength" type="number"> | 			<FormInput v-model="maxNoteTextLength" type="number" class="_formBlock"> | ||||||
| 			<template #prefix><i class="fas fa-pencil-alt"></i></template> | 				<template #prefix><i class="fas fa-pencil-alt"></i></template> | ||||||
| 			<span>{{ $ts.maxNoteTextLength }}</span> | 				<template #label>{{ $ts.maxNoteTextLength }}</template> | ||||||
| 		</FormInput> | 			</FormInput> | ||||||
| 
 | 
 | ||||||
| 		<FormSwitch v-model="enableLocalTimeline">{{ $ts.enableLocalTimeline }}</FormSwitch> | 			<FormSection> | ||||||
| 		<FormSwitch v-model="enableGlobalTimeline">{{ $ts.enableGlobalTimeline }}</FormSwitch> | 				<FormSwitch v-model="enableLocalTimeline" class="_formBlock">{{ $ts.enableLocalTimeline }}</FormSwitch> | ||||||
| 		<FormInfo>{{ $ts.disablingTimelinesInfo }}</FormInfo> | 				<FormSwitch v-model="enableGlobalTimeline" class="_formBlock">{{ $ts.enableGlobalTimeline }}</FormSwitch> | ||||||
| 
 | 				<FormInfo class="_formBlock">{{ $ts.disablingTimelinesInfo }}</FormInfo> | ||||||
| 		<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> | 			</FormSection> | ||||||
|  | 		</div> | ||||||
| 	</FormSuspense> | 	</FormSuspense> | ||||||
| </FormBase> | </MkSpacer> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent } from 'vue'; | import { defineComponent } from 'vue'; | ||||||
| import FormSwitch from '@/components/debobigego/switch.vue'; | import FormSwitch from '@/components/form/switch.vue'; | ||||||
| import FormInput from '@/components/debobigego/input.vue'; | import FormInput from '@/components/form/input.vue'; | ||||||
| import FormButton from '@/components/debobigego/button.vue'; | import FormTextarea from '@/components/form/textarea.vue'; | ||||||
| import FormBase from '@/components/debobigego/base.vue'; | import FormInfo from '@/components/ui/info.vue'; | ||||||
| import FormGroup from '@/components/debobigego/group.vue'; | import FormSection from '@/components/form/section.vue'; | ||||||
| import FormTextarea from '@/components/debobigego/textarea.vue'; | import FormSplit from '@/components/form/split.vue'; | ||||||
| import FormInfo from '@/components/debobigego/info.vue'; | import FormSuspense from '@/components/form/suspense.vue'; | ||||||
| import FormSuspense from '@/components/debobigego/suspense.vue'; |  | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import * as symbols from '@/symbols'; | import * as symbols from '@/symbols'; | ||||||
| import { fetchInstance } from '@/instance'; | import { fetchInstance } from '@/instance'; | ||||||
|  | @ -75,12 +78,11 @@ export default defineComponent({ | ||||||
| 	components: { | 	components: { | ||||||
| 		FormSwitch, | 		FormSwitch, | ||||||
| 		FormInput, | 		FormInput, | ||||||
| 		FormBase, | 		FormSuspense, | ||||||
| 		FormGroup, |  | ||||||
| 		FormButton, |  | ||||||
| 		FormTextarea, | 		FormTextarea, | ||||||
| 		FormInfo, | 		FormInfo, | ||||||
| 		FormSuspense, | 		FormSection, | ||||||
|  | 		FormSplit, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	emits: ['info'], | 	emits: ['info'], | ||||||
|  | @ -91,6 +93,12 @@ export default defineComponent({ | ||||||
| 				title: this.$ts.general, | 				title: this.$ts.general, | ||||||
| 				icon: 'fas fa-cog', | 				icon: 'fas fa-cog', | ||||||
| 				bg: 'var(--bg)', | 				bg: 'var(--bg)', | ||||||
|  | 				actions: [{ | ||||||
|  | 					asFullButton: true, | ||||||
|  | 					icon: 'fas fa-check', | ||||||
|  | 					text: this.$ts.save, | ||||||
|  | 					handler: this.save, | ||||||
|  | 				}], | ||||||
| 			}, | 			}, | ||||||
| 			name: null, | 			name: null, | ||||||
| 			description: null, | 			description: null, | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ | ||||||
| 				<template #prefix><i class="fas fa-search"></i></template> | 				<template #prefix><i class="fas fa-search"></i></template> | ||||||
| 				<template #label>{{ $ts.host }}</template> | 				<template #label>{{ $ts.host }}</template> | ||||||
| 			</MkInput> | 			</MkInput> | ||||||
| 			<div class="_inputSplit" style="margin-top: var(--margin);"> | 			<FormSplit style="margin-top: var(--margin);"> | ||||||
| 				<MkSelect v-model="state"> | 				<MkSelect v-model="state"> | ||||||
| 					<template #label>{{ $ts.state }}</template> | 					<template #label>{{ $ts.state }}</template> | ||||||
| 					<option value="all">{{ $ts.all }}</option> | 					<option value="all">{{ $ts.all }}</option> | ||||||
|  | @ -38,7 +38,7 @@ | ||||||
| 					<option value="+driveFiles">{{ $ts.driveFilesCount }} ({{ $ts.descendingOrder }})</option> | 					<option value="+driveFiles">{{ $ts.driveFilesCount }} ({{ $ts.descendingOrder }})</option> | ||||||
| 					<option value="-driveFiles">{{ $ts.driveFilesCount }} ({{ $ts.ascendingOrder }})</option> | 					<option value="-driveFiles">{{ $ts.driveFilesCount }} ({{ $ts.ascendingOrder }})</option> | ||||||
| 				</MkSelect> | 				</MkSelect> | ||||||
| 			</div> | 			</FormSplit> | ||||||
| 		</div> | 		</div> | ||||||
| 
 | 
 | ||||||
| 		<MkPagination v-slot="{items}" ref="instances" :key="host + state" :pagination="pagination"> | 		<MkPagination v-slot="{items}" ref="instances" :key="host + state" :pagination="pagination"> | ||||||
|  | @ -101,6 +101,7 @@ import MkButton from '@/components/ui/button.vue'; | ||||||
| import MkInput from '@/components/form/input.vue'; | import MkInput from '@/components/form/input.vue'; | ||||||
| import MkSelect from '@/components/form/select.vue'; | import MkSelect from '@/components/form/select.vue'; | ||||||
| import MkPagination from '@/components/ui/pagination.vue'; | import MkPagination from '@/components/ui/pagination.vue'; | ||||||
|  | import FormSplit from '@/components/form/split.vue'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import * as symbols from '@/symbols'; | import * as symbols from '@/symbols'; | ||||||
| 
 | 
 | ||||||
|  | @ -110,6 +111,7 @@ export default defineComponent({ | ||||||
| 		MkInput, | 		MkInput, | ||||||
| 		MkSelect, | 		MkSelect, | ||||||
| 		MkPagination, | 		MkPagination, | ||||||
|  | 		FormSplit, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	emits: ['info'], | 	emits: ['info'], | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ | ||||||
| 		<div class="_formBlock uawsfosz"> | 		<div class="_formBlock uawsfosz"> | ||||||
| 			<div class="meter"><div :style="meterStyle"></div></div> | 			<div class="meter"><div :style="meterStyle"></div></div> | ||||||
| 		</div> | 		</div> | ||||||
| 		<div class="_inputSplit _formBlock"> | 		<FormSplit> | ||||||
| 			<MkKeyValue class="_formBlock"> | 			<MkKeyValue class="_formBlock"> | ||||||
| 				<template #key>{{ $ts.capacity }}</template> | 				<template #key>{{ $ts.capacity }}</template> | ||||||
| 				<template #value>{{ bytes(capacity, 1) }}</template> | 				<template #value>{{ bytes(capacity, 1) }}</template> | ||||||
|  | @ -14,7 +14,7 @@ | ||||||
| 				<template #key>{{ $ts.inUse }}</template> | 				<template #key>{{ $ts.inUse }}</template> | ||||||
| 				<template #value>{{ bytes(usage, 1) }}</template> | 				<template #value>{{ bytes(usage, 1) }}</template> | ||||||
| 			</MkKeyValue> | 			</MkKeyValue> | ||||||
| 		</div> | 		</FormSplit> | ||||||
| 	</FormSection> | 	</FormSection> | ||||||
| 
 | 
 | ||||||
| 	<FormSection> | 	<FormSection> | ||||||
|  | @ -38,6 +38,7 @@ import * as tinycolor from 'tinycolor2'; | ||||||
| import FormLink from '@/components/form/link.vue'; | import FormLink from '@/components/form/link.vue'; | ||||||
| import FormSection from '@/components/form/section.vue'; | import FormSection from '@/components/form/section.vue'; | ||||||
| import MkKeyValue from '@/components/key-value.vue'; | import MkKeyValue from '@/components/key-value.vue'; | ||||||
|  | import FormSplit from '@/components/form/split.vue'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import bytes from '@/filters/bytes'; | import bytes from '@/filters/bytes'; | ||||||
| import * as symbols from '@/symbols'; | import * as symbols from '@/symbols'; | ||||||
|  | @ -49,6 +50,7 @@ export default defineComponent({ | ||||||
| 		FormLink, | 		FormLink, | ||||||
| 		FormSection, | 		FormSection, | ||||||
| 		MkKeyValue, | 		MkKeyValue, | ||||||
|  | 		FormSplit, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	emits: ['info'], | 	emits: ['info'], | ||||||
|  |  | ||||||
|  | @ -386,16 +386,6 @@ hr { | ||||||
| 	backdrop-filter: var(--blur, blur(15px)); | 	backdrop-filter: var(--blur, blur(15px)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ._inputSplit { |  | ||||||
| 	display: grid; |  | ||||||
| 	grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); |  | ||||||
| 	grid-gap: 12px; |  | ||||||
| 
 |  | ||||||
| 	> * { |  | ||||||
| 		margin: 0 !important; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ._formBlock { | ._formBlock { | ||||||
| 	margin: 1.5em 0; | 	margin: 1.5em 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -47,6 +47,7 @@ module.exports = { | ||||||
| 				loader: 'vue-loader', | 				loader: 'vue-loader', | ||||||
| 				options: { | 				options: { | ||||||
| 					cssSourceMap: false, | 					cssSourceMap: false, | ||||||
|  | 					reactivityTransform: true, | ||||||
| 					compilerOptions: { | 					compilerOptions: { | ||||||
| 						preserveWhitespace: false | 						preserveWhitespace: false | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
|  | @ -6162,10 +6162,10 @@ vue-eslint-parser@^8.0.1: | ||||||
|     lodash "^4.17.21" |     lodash "^4.17.21" | ||||||
|     semver "^7.3.5" |     semver "^7.3.5" | ||||||
| 
 | 
 | ||||||
| vue-loader@16.8.3: | vue-loader@17.0.0: | ||||||
|   version "16.8.3" |   version "17.0.0" | ||||||
|   resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.8.3.tgz#d43e675def5ba9345d6c7f05914c13d861997087" |   resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-17.0.0.tgz#2eaa80aab125b19f00faa794b5bd867b17f85acb" | ||||||
|   integrity sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA== |   integrity sha512-OWSXjrzIvbF2LtOUmxT3HYgwwubbfFelN8PAP9R9dwpIkj48TVioHhWWSx7W7fk+iF5cgg3CBJRxwTdtLU4Ecg== | ||||||
|   dependencies: |   dependencies: | ||||||
|     chalk "^4.1.0" |     chalk "^4.1.0" | ||||||
|     hash-sum "^2.0.0" |     hash-sum "^2.0.0" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue