diff --git a/src/client/pages/federation.vue b/src/client/pages/federation.vue index aac94e00af..eae6a05367 100644 --- a/src/client/pages/federation.vue +++ b/src/client/pages/federation.vue @@ -116,7 +116,8 @@ export default defineComponent({ return { [symbols.PAGE_INFO]: { title: this.$ts.federation, - icon: 'fas fa-globe' + icon: 'fas fa-globe', + bg: 'var(--bg)', }, host: '', state: 'federating', diff --git a/src/client/pages/instance/abuses.vue b/src/client/pages/instance/abuses.vue index a66847938d..29da8cc2c5 100644 --- a/src/client/pages/instance/abuses.vue +++ b/src/client/pages/instance/abuses.vue @@ -86,7 +86,8 @@ export default defineComponent({ return { [symbols.PAGE_INFO]: { title: this.$ts.abuseReports, - icon: 'fas fa-exclamation-circle' + icon: 'fas fa-exclamation-circle', + bg: 'var(--bg)', }, searchUsername: '', searchHost: '', diff --git a/src/client/pages/instance/ads.vue b/src/client/pages/instance/ads.vue index 8742d0bda1..c54c1c0280 100644 --- a/src/client/pages/instance/ads.vue +++ b/src/client/pages/instance/ads.vue @@ -64,7 +64,8 @@ export default defineComponent({ return { [symbols.PAGE_INFO]: { title: this.$ts.ads, - icon: 'fas fa-audio-description' + icon: 'fas fa-audio-description', + bg: 'var(--bg)', }, ads: [], } diff --git a/src/client/pages/instance/announcements.vue b/src/client/pages/instance/announcements.vue index 35d676cf28..e4f7334c05 100644 --- a/src/client/pages/instance/announcements.vue +++ b/src/client/pages/instance/announcements.vue @@ -43,7 +43,8 @@ export default defineComponent({ return { [symbols.PAGE_INFO]: { title: this.$ts.announcements, - icon: 'fas fa-broadcast-tower' + icon: 'fas fa-broadcast-tower', + bg: 'var(--bg)', }, announcements: [], } diff --git a/src/client/pages/instance/emojis.vue b/src/client/pages/instance/emojis.vue index 6118d869e9..219955dc45 100644 --- a/src/client/pages/instance/emojis.vue +++ b/src/client/pages/instance/emojis.vue @@ -78,6 +78,7 @@ export default defineComponent({ [symbols.PAGE_INFO]: { title: this.$ts.customEmojis, icon: 'fas fa-laugh', + bg: 'var(--bg)', action: { icon: 'fas fa-plus', handler: this.add diff --git a/src/client/pages/instance/files.vue b/src/client/pages/instance/files.vue index df2431ad02..55189cfd84 100644 --- a/src/client/pages/instance/files.vue +++ b/src/client/pages/instance/files.vue @@ -1,20 +1,14 @@ <template> <div class="xrmjdkdw"> - <div class="_section"> - <div class="_content"> - <MkButton primary @click="clear()"><i class="fas fa-trash-alt"></i> {{ $ts.clearCachedFiles }}</MkButton> - </div> - </div> - - <div class="_section lookup"> - <div class="_title"><i class="fas fa-search"></i> {{ $ts.lookup }}</div> - <div class="_content"> - <MkInput class="target" v-model="q" type="text" @enter="find()"> + <MkContainer :foldable="true" class="lookup"> + <template #header><i class="fas fa-search"></i> {{ $ts.lookup }}</template> + <div class="xrmjdkdw-lookup"> + <MkInput class="item" v-model="q" type="text" @enter="find()"> <template #label>{{ $ts.fileIdOrUrl }}</template> </MkInput> <MkButton @click="find()" primary><i class="fas fa-search"></i> {{ $ts.lookup }}</MkButton> </div> - </div> + </MkContainer> <div class="_section"> <div class="_content"> @@ -31,7 +25,7 @@ </div> <div class="inputs" style="display: flex; padding-top: 1.2em;"> <MkInput v-model="type" :debounce="true" type="search" style="margin: 0; flex: 1;"> - <template #label>{{ $ts.type }}</template> + <template #label>MIME type</template> </MkInput> </div> <MkPagination :pagination="pagination" #default="{items}" class="urempief" ref="files"> @@ -66,6 +60,7 @@ import MkButton from '@client/components/ui/button.vue'; import MkInput from '@client/components/form/input.vue'; import MkSelect from '@client/components/form/select.vue'; import MkPagination from '@client/components/ui/pagination.vue'; +import MkContainer from '@client/components/ui/container.vue'; import MkDriveFileThumbnail from '@client/components/drive-file-thumbnail.vue'; import bytes from '@client/filters/bytes'; import * as os from '@client/os'; @@ -77,6 +72,7 @@ export default defineComponent({ MkInput, MkSelect, MkPagination, + MkContainer, MkDriveFileThumbnail, }, @@ -86,7 +82,13 @@ export default defineComponent({ return { [symbols.PAGE_INFO]: { title: this.$ts.files, - icon: 'fas fa-cloud' + icon: 'fas fa-cloud', + bg: 'var(--bg)', + actions: [{ + text: this.$ts.clearCachedFiles, + icon: 'fas fa-trash-alt', + handler: this.clear + }] }, q: null, origin: 'local', @@ -161,6 +163,10 @@ export default defineComponent({ .xrmjdkdw { margin: var(--margin); + > .lookup { + margin-bottom: 16px; + } + .urempief { margin-top: var(--margin); @@ -192,4 +198,12 @@ export default defineComponent({ } } } + +.xrmjdkdw-lookup { + padding: 16px; + + > .item { + margin-bottom: 16px; + } +} </style> diff --git a/src/client/pages/instance/index.link.vue b/src/client/pages/instance/index.link.vue new file mode 100644 index 0000000000..e1f4773800 --- /dev/null +++ b/src/client/pages/instance/index.link.vue @@ -0,0 +1,97 @@ +<template> +<div class="qmfkfnzh"> + <a class="main _button" :href="to" target="_blank" v-if="external"> + <span class="icon"><slot name="icon"></slot></span> + <span class="text"><slot></slot></span> + </a> + <MkA class="main _button" :class="{ active }" :to="to" :behavior="behavior" v-else> + <span class="icon"><slot name="icon"></slot></span> + <span class="text"><slot></slot></span> + </MkA> +</div> +</template> + +<script lang="ts"> +import { defineComponent } from 'vue'; + +export default defineComponent({ + props: { + to: { + type: String, + required: true + }, + active: { + type: Boolean, + required: false + }, + external: { + type: Boolean, + required: false + }, + behavior: { + type: String, + required: false, + }, + }, + data() { + return { + }; + } +}); +</script> + +<style lang="scss" scoped> +.qmfkfnzh { + > .main { + display: flex; + align-items: center; + width: 100%; + box-sizing: border-box; + padding: 10px 16px 10px 14px; + border-radius: 999px; + font-size: 0.9em; + + &:hover { + text-decoration: none; + background: var(--panelHighlight); + } + + &.active { + color: var(--accent); + background: var(--accentedBg); + } + + > .icon { + width: 32px; + margin-right: 2px; + flex-shrink: 0; + text-align: center; + opacity: 0.8; + + &:empty { + display: none; + + & + .text { + padding-left: 4px; + } + } + } + + > .text { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + padding-right: 12px; + } + + > .right { + margin-left: auto; + opacity: 0.7; + + > .text:not(:empty) { + margin-right: 0.75em; + } + } + } +} +</style> diff --git a/src/client/pages/instance/index.vue b/src/client/pages/instance/index.vue index 657a654e51..780dd099b6 100644 --- a/src/client/pages/instance/index.vue +++ b/src/client/pages/instance/index.vue @@ -1,51 +1,49 @@ <template> <div class="hiyeyicy" :class="{ wide: !narrow }" ref="el"> <div class="nav" v-if="!narrow || page == null"> - <FormBase> - <FormGroup> - <div class="_debobigegoItem"> - <div class="_debobigegoPanel lxpfedzu"> - <img :src="$instance.iconUrl || '/favicon.ico'" alt="" class="icon"/> - </div> + <div class="group"> + <div class="_debobigegoItem"> + <div class="_debobigegoPanel lxpfedzu"> + <img :src="$instance.iconUrl || '/favicon.ico'" alt="" class="icon"/> </div> - <FormLink :active="page === 'overview'" replace to="/instance/overview"><template #icon><i class="fas fa-tachometer-alt"></i></template>{{ $ts.overview }}</FormLink> - </FormGroup> - <FormGroup> - <template #label>{{ $ts.quickAction }}</template> - <FormButton @click="lookup"><i class="fas fa-search"></i> {{ $ts.lookup }}</FormButton> - <FormButton v-if="$instance.disableRegistration" @click="invite"><i class="fas fa-user"></i> {{ $ts.invite }}</FormButton> - </FormGroup> - <FormGroup> - <template #label>{{ $ts.administration }}</template> - <FormLink :active="page === 'users'" replace to="/instance/users"><template #icon><i class="fas fa-users"></i></template>{{ $ts.users }}</FormLink> - <FormLink :active="page === 'emojis'" replace to="/instance/emojis"><template #icon><i class="fas fa-laugh"></i></template>{{ $ts.customEmojis }}</FormLink> - <FormLink :active="page === 'federation'" replace to="/instance/federation"><template #icon><i class="fas fa-globe"></i></template>{{ $ts.federation }}</FormLink> - <FormLink :active="page === 'queue'" replace to="/instance/queue"><template #icon><i class="fas fa-clipboard-list"></i></template>{{ $ts.jobQueue }}</FormLink> - <FormLink :active="page === 'files'" replace to="/instance/files"><template #icon><i class="fas fa-cloud"></i></template>{{ $ts.files }}</FormLink> - <FormLink :active="page === 'announcements'" replace to="/instance/announcements"><template #icon><i class="fas fa-broadcast-tower"></i></template>{{ $ts.announcements }}</FormLink> - <FormLink :active="page === 'ads'" replace to="/instance/ads"><template #icon><i class="fas fa-audio-description"></i></template>{{ $ts.ads }}</FormLink> - <FormLink :active="page === 'abuses'" replace to="/instance/abuses"><template #icon><i class="fas fa-exclamation-circle"></i></template>{{ $ts.abuseReports }}</FormLink> - </FormGroup> - <FormGroup> - <template #label>{{ $ts.settings }}</template> - <FormLink :active="page === 'settings'" replace to="/instance/settings"><template #icon><i class="fas fa-cog"></i></template>{{ $ts.general }}</FormLink> - <FormLink :active="page === 'files-settings'" replace to="/instance/files-settings"><template #icon><i class="fas fa-cloud"></i></template>{{ $ts.files }}</FormLink> - <FormLink :active="page === 'email-settings'" replace to="/instance/email-settings"><template #icon><i class="fas fa-envelope"></i></template>{{ $ts.emailServer }}</FormLink> - <FormLink :active="page === 'object-storage'" replace to="/instance/object-storage"><template #icon><i class="fas fa-cloud"></i></template>{{ $ts.objectStorage }}</FormLink> - <FormLink :active="page === 'security'" replace to="/instance/security"><template #icon><i class="fas fa-lock"></i></template>{{ $ts.security }}</FormLink> - <FormLink :active="page === 'service-worker'" replace to="/instance/service-worker"><template #icon><i class="fas fa-bolt"></i></template>ServiceWorker</FormLink> - <FormLink :active="page === 'relays'" replace to="/instance/relays"><template #icon><i class="fas fa-globe"></i></template>{{ $ts.relays }}</FormLink> - <FormLink :active="page === 'integrations'" replace to="/instance/integrations"><template #icon><i class="fas fa-share-alt"></i></template>{{ $ts.integration }}</FormLink> - <FormLink :active="page === 'instance-block'" replace to="/instance/instance-block"><template #icon><i class="fas fa-ban"></i></template>{{ $ts.instanceBlocking }}</FormLink> - <FormLink :active="page === 'proxy-account'" replace to="/instance/proxy-account"><template #icon><i class="fas fa-ghost"></i></template>{{ $ts.proxyAccount }}</FormLink> - <FormLink :active="page === 'other-settings'" replace to="/instance/other-settings"><template #icon><i class="fas fa-cogs"></i></template>{{ $ts.other }}</FormLink> - </FormGroup> - <FormGroup> - <template #label>{{ $ts.info }}</template> - <FormLink :active="page === 'database'" replace to="/instance/database"><template #icon><i class="fas fa-database"></i></template>{{ $ts.database }}</FormLink> - <FormLink :active="page === 'logs'" replace to="/instance/logs"><template #icon><i class="fas fa-stream"></i></template>{{ $ts.logs }}</FormLink> - </FormGroup> - </FormBase> + </div> + <XLink :active="page === 'overview'" replace to="/instance/overview"><template #icon><i class="fas fa-tachometer-alt"></i></template>{{ $ts.overview }}</XLink> + </div> + <div class="group"> + <div class="label">{{ $ts.quickAction }}</div> + <FormButton @click="lookup"><i class="fas fa-search"></i> {{ $ts.lookup }}</FormButton> + <FormButton v-if="$instance.disableRegistration" @click="invite"><i class="fas fa-user"></i> {{ $ts.invite }}</FormButton> + </div> + <div class="group"> + <div class="label">{{ $ts.administration }}</div> + <XLink :active="page === 'users'" replace to="/instance/users"><template #icon><i class="fas fa-users"></i></template>{{ $ts.users }}</XLink> + <XLink :active="page === 'emojis'" replace to="/instance/emojis"><template #icon><i class="fas fa-laugh"></i></template>{{ $ts.customEmojis }}</XLink> + <XLink :active="page === 'federation'" replace to="/instance/federation"><template #icon><i class="fas fa-globe"></i></template>{{ $ts.federation }}</XLink> + <XLink :active="page === 'queue'" replace to="/instance/queue"><template #icon><i class="fas fa-clipboard-list"></i></template>{{ $ts.jobQueue }}</XLink> + <XLink :active="page === 'files'" replace to="/instance/files"><template #icon><i class="fas fa-cloud"></i></template>{{ $ts.files }}</XLink> + <XLink :active="page === 'announcements'" replace to="/instance/announcements"><template #icon><i class="fas fa-broadcast-tower"></i></template>{{ $ts.announcements }}</XLink> + <XLink :active="page === 'ads'" replace to="/instance/ads"><template #icon><i class="fas fa-audio-description"></i></template>{{ $ts.ads }}</XLink> + <XLink :active="page === 'abuses'" replace to="/instance/abuses"><template #icon><i class="fas fa-exclamation-circle"></i></template>{{ $ts.abuseReports }}</XLink> + </div> + <div class="group"> + <div class="label">{{ $ts.settings }}</div> + <XLink :active="page === 'settings'" replace to="/instance/settings"><template #icon><i class="fas fa-cog"></i></template>{{ $ts.general }}</XLink> + <XLink :active="page === 'files-settings'" replace to="/instance/files-settings"><template #icon><i class="fas fa-cloud"></i></template>{{ $ts.files }}</XLink> + <XLink :active="page === 'email-settings'" replace to="/instance/email-settings"><template #icon><i class="fas fa-envelope"></i></template>{{ $ts.emailServer }}</XLink> + <XLink :active="page === 'object-storage'" replace to="/instance/object-storage"><template #icon><i class="fas fa-cloud"></i></template>{{ $ts.objectStorage }}</XLink> + <XLink :active="page === 'security'" replace to="/instance/security"><template #icon><i class="fas fa-lock"></i></template>{{ $ts.security }}</XLink> + <XLink :active="page === 'service-worker'" replace to="/instance/service-worker"><template #icon><i class="fas fa-bolt"></i></template>ServiceWorker</XLink> + <XLink :active="page === 'relays'" replace to="/instance/relays"><template #icon><i class="fas fa-globe"></i></template>{{ $ts.relays }}</XLink> + <XLink :active="page === 'integrations'" replace to="/instance/integrations"><template #icon><i class="fas fa-share-alt"></i></template>{{ $ts.integration }}</XLink> + <XLink :active="page === 'instance-block'" replace to="/instance/instance-block"><template #icon><i class="fas fa-ban"></i></template>{{ $ts.instanceBlocking }}</XLink> + <XLink :active="page === 'proxy-account'" replace to="/instance/proxy-account"><template #icon><i class="fas fa-ghost"></i></template>{{ $ts.proxyAccount }}</XLink> + <XLink :active="page === 'other-settings'" replace to="/instance/other-settings"><template #icon><i class="fas fa-cogs"></i></template>{{ $ts.other }}</XLink> + </div> + <div class="group"> + <div class="label">{{ $ts.info }}</div> + <XLink :active="page === 'database'" replace to="/instance/database"><template #icon><i class="fas fa-database"></i></template>{{ $ts.database }}</XLink> + <XLink :active="page === 'logs'" replace to="/instance/logs"><template #icon><i class="fas fa-stream"></i></template>{{ $ts.logs }}</XLink> + </div> </div> <div class="main"> <component :is="component" :key="page" @info="onInfo" v-bind="pageProps"/> @@ -56,7 +54,7 @@ <script lang="ts"> import { computed, defineAsyncComponent, defineComponent, nextTick, onMounted, reactive, ref, watch } from 'vue'; import { i18n } from '@client/i18n'; -import FormLink from '@client/components/debobigego/link.vue'; +import XLink from './index.link.vue'; import FormGroup from '@client/components/debobigego/group.vue'; import FormBase from '@client/components/debobigego/base.vue'; import FormButton from '@client/components/debobigego/button.vue'; @@ -68,7 +66,7 @@ import { lookupUser } from '@client/scripts/lookup-user'; export default defineComponent({ components: { FormBase, - FormLink, + XLink, FormGroup, FormButton, }, @@ -214,15 +212,25 @@ export default defineComponent({ .hiyeyicy { &.wide { display: flex; - max-width: 1100px; margin: 0 auto; height: 100%; > .nav { width: 32%; + max-width: 320px; box-sizing: border-box; border-right: solid 0.5px var(--divider); overflow: auto; + + > .group { + padding: 16px; + + > .label { + font-size: 0.9em; + opacity: 0.7; + margin: 0 0 8px 12px; + } + } } > .main { diff --git a/src/client/pages/instance/overview.vue b/src/client/pages/instance/overview.vue index 28dcfc03bf..61fbc03c64 100644 --- a/src/client/pages/instance/overview.vue +++ b/src/client/pages/instance/overview.vue @@ -86,7 +86,8 @@ export default defineComponent({ return { [symbols.PAGE_INFO]: { title: this.$ts.overview, - icon: 'fas fa-tachometer-alt' + icon: 'fas fa-tachometer-alt', + bg: 'var(--bg)', }, page: 'index', version, diff --git a/src/client/pages/instance/users.vue b/src/client/pages/instance/users.vue index 7671387f01..b72d3f7d3c 100644 --- a/src/client/pages/instance/users.vue +++ b/src/client/pages/instance/users.vue @@ -6,15 +6,15 @@ </div> <div class="users"> - <div class="inputs" style="display: flex;"> - <MkSelect v-model="sort" style="margin: 0; flex: 1;"> + <div class="inputs"> + <MkSelect v-model="sort" style="flex: 1;"> <template #label>{{ $ts.sort }}</template> <option value="-createdAt">{{ $ts.registeredDate }} ({{ $ts.ascendingOrder }})</option> <option value="+createdAt">{{ $ts.registeredDate }} ({{ $ts.descendingOrder }})</option> <option value="-updatedAt">{{ $ts.lastUsed }} ({{ $ts.ascendingOrder }})</option> <option value="+updatedAt">{{ $ts.lastUsed }} ({{ $ts.descendingOrder }})</option> </MkSelect> - <MkSelect v-model="state" style="margin: 0; flex: 1;"> + <MkSelect v-model="state" style="flex: 1;"> <template #label>{{ $ts.state }}</template> <option value="all">{{ $ts.all }}</option> <option value="available">{{ $ts.normal }}</option> @@ -23,18 +23,18 @@ <option value="silenced">{{ $ts.silence }}</option> <option value="suspended">{{ $ts.suspend }}</option> </MkSelect> - <MkSelect v-model="origin" style="margin: 0; flex: 1;"> + <MkSelect v-model="origin" style="flex: 1;"> <template #label>{{ $ts.instance }}</template> <option value="combined">{{ $ts.all }}</option> <option value="local">{{ $ts.local }}</option> <option value="remote">{{ $ts.remote }}</option> </MkSelect> </div> - <div class="inputs" style="display: flex; padding-top: 1.2em;"> - <MkInput v-model="searchUsername" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:modelValue="$refs.users.reload()"> + <div class="inputs"> + <MkInput v-model="searchUsername" style="flex: 1;" type="text" spellcheck="false" @update:modelValue="$refs.users.reload()"> <template #label>{{ $ts.username }}</template> </MkInput> - <MkInput v-model="searchHost" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:modelValue="$refs.users.reload()" :disabled="pagination.params().origin === 'local'"> + <MkInput v-model="searchHost" style="flex: 1;" type="text" spellcheck="false" @update:modelValue="$refs.users.reload()" :disabled="pagination.params().origin === 'local'"> <template #label>{{ $ts.host }}</template> </MkInput> </div> @@ -90,6 +90,7 @@ export default defineComponent({ [symbols.PAGE_INFO]: { title: this.$ts.users, icon: 'fas fa-users', + bg: 'var(--bg)', action: { icon: 'fas fa-search', handler: this.searchUser @@ -178,6 +179,19 @@ export default defineComponent({ > .users { margin: var(--margin); + + > .inputs { + display: flex; + margin-bottom: 16px; + + > * { + margin-right: 16px; + + &:last-child { + margin-right: 0; + } + } + } > .users { margin-top: var(--margin); diff --git a/src/client/pages/settings/index.vue b/src/client/pages/settings/index.vue index 25c83a823f..399f4049b6 100644 --- a/src/client/pages/settings/index.vue +++ b/src/client/pages/settings/index.vue @@ -1,11 +1,11 @@ <template> <div class="vvcocwet" :class="{ wide: !narrow }" ref="el"> <div class="nav" v-if="!narrow || page == null"> - <div class="group"> + <div class="group accounts"> <MkAvatar :user="$i" class="avatar"/> <XLink :active="page === 'accounts'" replace to="/settings/accounts"><template #icon><i class="fas fa-users"></i></template>{{ $ts.accounts }}</XLink> </div> - <MkInfo v-if="emailNotConfigured || true" warn>{{ $ts.emailNotConfiguredWarning }} <MkA to="/settings/email" class="_link">{{ $ts.configure }}</MkA></MkInfo> + <MkInfo v-if="emailNotConfigured || true" warn class="info">{{ $ts.emailNotConfiguredWarning }} <MkA to="/settings/email" class="_link">{{ $ts.configure }}</MkA></MkInfo> <div class="group"> <div class="label">{{ $ts.basicSettings }}</div> <XLink :active="page === 'profile'" replace to="/settings/profile"><template #icon><i class="fas fa-user"></i></template>{{ $ts.profile }}</XLink> @@ -207,7 +207,20 @@ export default defineComponent({ > .label { font-size: 0.9em; opacity: 0.7; - margin: 0 0 8px 8px; + margin: 0 0 8px 12px; + } + } + + > .info { + margin: 0 16px; + } + + > .accounts { + > .avatar { + display: block; + width: 50px; + height: 50px; + margin: 0 auto 8px auto; } } }