summaryrefslogtreecommitdiff
path: root/src/client/pages
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2021-04-23 18:25:44 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2021-04-23 18:25:44 +0900
commit37dc1c9a82c72ca1d28ab05a55269eac650133db (patch)
tree573d6d6f6f4ffd5b63ef137543ab685c40c31508 /src/client/pages
parentMerge branch 'develop' (diff)
parentUpdate package.json (diff)
downloadmisskey-37dc1c9a82c72ca1d28ab05a55269eac650133db.tar.gz
misskey-37dc1c9a82c72ca1d28ab05a55269eac650133db.tar.bz2
misskey-37dc1c9a82c72ca1d28ab05a55269eac650133db.zip
Merge branch 'develop'
Diffstat (limited to 'src/client/pages')
-rw-r--r--src/client/pages/_error_.vue6
-rw-r--r--src/client/pages/about-misskey.vue8
-rw-r--r--src/client/pages/about.vue4
-rw-r--r--src/client/pages/advanced-theme-editor.vue6
-rw-r--r--src/client/pages/announcements.vue6
-rw-r--r--src/client/pages/api-console.vue6
-rw-r--r--src/client/pages/channel-editor.vue13
-rw-r--r--src/client/pages/channel.vue15
-rw-r--r--src/client/pages/channels.vue15
-rw-r--r--src/client/pages/clip.vue9
-rw-r--r--src/client/pages/doc.vue3
-rw-r--r--src/client/pages/docs.vue4
-rw-r--r--src/client/pages/drive.vue3
-rw-r--r--src/client/pages/explore.vue25
-rw-r--r--src/client/pages/favorites.vue3
-rw-r--r--src/client/pages/featured.vue4
-rw-r--r--src/client/pages/follow-requests.vue8
-rw-r--r--src/client/pages/instance-info.vue8
-rw-r--r--src/client/pages/instance/abuses.vue17
-rw-r--r--src/client/pages/instance/announcements.vue57
-rw-r--r--src/client/pages/instance/bot-protection.vue138
-rw-r--r--src/client/pages/instance/database.vue60
-rw-r--r--src/client/pages/instance/email-settings.vue127
-rw-r--r--src/client/pages/instance/emoji-edit-dialog.vue22
-rw-r--r--src/client/pages/instance/emojis.vue222
-rw-r--r--src/client/pages/instance/federation.vue117
-rw-r--r--src/client/pages/instance/file-dialog.vue11
-rw-r--r--src/client/pages/instance/files-settings.vue92
-rw-r--r--src/client/pages/instance/files.vue19
-rw-r--r--src/client/pages/instance/index.vue362
-rw-r--r--src/client/pages/instance/instance-block.vue71
-rw-r--r--src/client/pages/instance/instance.vue6
-rw-r--r--src/client/pages/instance/integrations-discord.vue85
-rw-r--r--src/client/pages/instance/integrations-github.vue85
-rw-r--r--src/client/pages/instance/integrations-twitter.vue85
-rw-r--r--src/client/pages/instance/integrations.vue73
-rw-r--r--src/client/pages/instance/logs.vue7
-rw-r--r--src/client/pages/instance/metrics.vue (renamed from src/client/pages/instance/index.metrics.vue)243
-rw-r--r--src/client/pages/instance/object-storage.vue154
-rw-r--r--src/client/pages/instance/other-settings.vue68
-rw-r--r--src/client/pages/instance/overview.vue135
-rw-r--r--src/client/pages/instance/proxy-account.vue86
-rw-r--r--src/client/pages/instance/queue.chart.vue64
-rw-r--r--src/client/pages/instance/queue.vue27
-rw-r--r--src/client/pages/instance/relays.vue53
-rw-r--r--src/client/pages/instance/security.vue77
-rw-r--r--src/client/pages/instance/service-worker.vue84
-rw-r--r--src/client/pages/instance/settings.vue611
-rw-r--r--src/client/pages/instance/user-dialog.vue233
-rw-r--r--src/client/pages/instance/users.vue264
-rw-r--r--src/client/pages/mentions.vue3
-rw-r--r--src/client/pages/messages.vue4
-rw-r--r--src/client/pages/messaging/index.vue10
-rw-r--r--src/client/pages/messaging/messaging-room.form.vue8
-rw-r--r--src/client/pages/messaging/messaging-room.message.vue4
-rw-r--r--src/client/pages/messaging/messaging-room.vue27
-rw-r--r--src/client/pages/mfm-cheat-sheet.vue3
-rw-r--r--src/client/pages/my-antennas/index.antenna.vue6
-rw-r--r--src/client/pages/my-antennas/index.vue8
-rw-r--r--src/client/pages/my-clips/index.vue8
-rw-r--r--src/client/pages/my-groups/group.vue6
-rw-r--r--src/client/pages/my-groups/index.vue12
-rw-r--r--src/client/pages/my-lists/index.vue8
-rw-r--r--src/client/pages/my-lists/list.vue6
-rw-r--r--src/client/pages/not-found.vue3
-rw-r--r--src/client/pages/note.vue6
-rw-r--r--src/client/pages/notifications.vue5
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.button.vue4
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.canvas.vue6
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.counter.vue6
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.if.vue6
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.image.vue7
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.note.vue4
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.number-input.vue6
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.post.vue4
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.radio-button.vue6
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.section.vue9
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.switch.vue6
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.text-input.vue6
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.text.vue4
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.textarea-input.vue6
-rw-r--r--src/client/pages/page-editor/els/page-editor.el.textarea.vue4
-rw-r--r--src/client/pages/page-editor/page-editor.container.vue13
-rw-r--r--src/client/pages/page-editor/page-editor.script-block.vue8
-rw-r--r--src/client/pages/page-editor/page-editor.vue31
-rw-r--r--src/client/pages/page.vue11
-rw-r--r--src/client/pages/pages.vue15
-rw-r--r--src/client/pages/preview.vue3
-rw-r--r--src/client/pages/reversi/game.board.vue18
-rw-r--r--src/client/pages/reversi/game.setting.vue8
-rw-r--r--src/client/pages/reversi/game.vue3
-rw-r--r--src/client/pages/reversi/index.vue3
-rw-r--r--src/client/pages/room/room.vue17
-rw-r--r--src/client/pages/scratchpad.vue8
-rw-r--r--src/client/pages/search.vue3
-rw-r--r--src/client/pages/settings/2fa.vue10
-rw-r--r--src/client/pages/settings/account-info.vue3
-rw-r--r--src/client/pages/settings/accounts.vue148
-rw-r--r--src/client/pages/settings/api.vue3
-rw-r--r--src/client/pages/settings/apps.vue6
-rw-r--r--src/client/pages/settings/deck.vue4
-rw-r--r--src/client/pages/settings/drive.vue7
-rw-r--r--src/client/pages/settings/email-address.vue5
-rw-r--r--src/client/pages/settings/email-notification.vue4
-rw-r--r--src/client/pages/settings/email.vue11
-rw-r--r--src/client/pages/settings/experimental-features.vue3
-rw-r--r--src/client/pages/settings/general.vue4
-rw-r--r--src/client/pages/settings/import-export.vue18
-rw-r--r--src/client/pages/settings/index.vue61
-rw-r--r--src/client/pages/settings/integration.vue11
-rw-r--r--src/client/pages/settings/mute-block.vue3
-rw-r--r--src/client/pages/settings/notifications.vue5
-rw-r--r--src/client/pages/settings/other.vue10
-rw-r--r--src/client/pages/settings/plugin.install.vue6
-rw-r--r--src/client/pages/settings/plugin.manage.vue8
-rw-r--r--src/client/pages/settings/plugin.vue8
-rw-r--r--src/client/pages/settings/privacy.vue3
-rw-r--r--src/client/pages/settings/profile.vue9
-rw-r--r--src/client/pages/settings/reaction.vue13
-rw-r--r--src/client/pages/settings/registry.keys.vue3
-rw-r--r--src/client/pages/settings/registry.value.vue8
-rw-r--r--src/client/pages/settings/registry.vue3
-rw-r--r--src/client/pages/settings/security.vue12
-rw-r--r--src/client/pages/settings/sidebar.vue8
-rw-r--r--src/client/pages/settings/sounds.vue12
-rw-r--r--src/client/pages/settings/theme.install.vue8
-rw-r--r--src/client/pages/settings/theme.manage.vue6
-rw-r--r--src/client/pages/settings/theme.vue14
-rw-r--r--src/client/pages/settings/update.vue3
-rw-r--r--src/client/pages/settings/word-mute.vue6
-rw-r--r--src/client/pages/share.vue4
-rw-r--r--src/client/pages/tag.vue4
-rw-r--r--src/client/pages/test.vue3
-rw-r--r--src/client/pages/theme-editor.vue10
-rw-r--r--src/client/pages/timeline.tutorial.vue12
-rw-r--r--src/client/pages/timeline.vue25
-rw-r--r--src/client/pages/user-ap-info.vue3
-rw-r--r--src/client/pages/user-info.vue176
-rw-r--r--src/client/pages/user/index.activity.vue4
-rw-r--r--src/client/pages/user/index.photos.vue4
-rw-r--r--src/client/pages/user/index.vue53
-rw-r--r--src/client/pages/v.vue2
-rw-r--r--src/client/pages/welcome.entrance.a.vue10
-rw-r--r--src/client/pages/welcome.entrance.b.vue8
-rw-r--r--src/client/pages/welcome.entrance.c.vue10
-rw-r--r--src/client/pages/welcome.setup.vue4
146 files changed, 2897 insertions, 2134 deletions
diff --git a/src/client/pages/_error_.vue b/src/client/pages/_error_.vue
index 67c1a1991c..6caecd6eaf 100644
--- a/src/client/pages/_error_.vue
+++ b/src/client/pages/_error_.vue
@@ -3,7 +3,7 @@
<div class="_section">
<div class="mjndxjch _content">
<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
- <p><Fa :icon="faExclamationTriangle"/> {{ $ts.pageLoadError }}</p>
+ <p><i class="fas fa-exclamation-triangle"></i> {{ $ts.pageLoadError }}</p>
<p>{{ $ts.pageLoadErrorDescription }}</p>
</div>
</div>
@@ -12,7 +12,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import * as symbols from '@client/symbols';
@@ -24,9 +23,8 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.error,
- icon: faExclamationTriangle
+ icon: 'fas fa-exclamation-triangle'
},
- faExclamationTriangle
};
},
});
diff --git a/src/client/pages/about-misskey.vue b/src/client/pages/about-misskey.vue
index aae8a7052a..1d57c80810 100644
--- a/src/client/pages/about-misskey.vue
+++ b/src/client/pages/about-misskey.vue
@@ -15,17 +15,17 @@
</section>
<FormGroup>
<FormLink to="https://github.com/misskey-dev/misskey" external>
- <template #icon><Fa :icon="faCode"/></template>
+ <template #icon><i class="fas fa-code"></i></template>
{{ $ts._aboutMisskey.source }}
<template #suffix>GitHub</template>
</FormLink>
<FormLink to="https://crowdin.com/project/misskey" external>
- <template #icon><Fa :icon="faLanguage"/></template>
+ <template #icon><i class="fas fa-language"></i></template>
{{ $ts._aboutMisskey.translation }}
<template #suffix>Crowdin</template>
</FormLink>
<FormLink to="https://www.patreon.com/syuilo" external>
- <template #icon><Fa :icon="faHandHoldingMedical"/></template>
+ <template #icon><i class="fas fa-hand-holding-medical"></i></template>
{{ $ts._aboutMisskey.donate }}
<template #suffix>Patreon</template>
</FormLink>
@@ -54,7 +54,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faInfoCircle, faCode, faLanguage, faHandHoldingMedical, } from '@fortawesome/free-solid-svg-icons';
import VanillaTilt from 'vanilla-tilt';
import { version } from '@client/config';
import FormLink from '@client/components/form/link.vue';
@@ -125,7 +124,6 @@ export default defineComponent({
easterEggReady: false,
easterEggEmojis: [],
easterEggEngine: null,
- faInfoCircle, faCode, faLanguage, faHandHoldingMedical,
}
},
diff --git a/src/client/pages/about.vue b/src/client/pages/about.vue
index 4084256cf4..4f70998eee 100644
--- a/src/client/pages/about.vue
+++ b/src/client/pages/about.vue
@@ -40,7 +40,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faInfoCircle } from '@fortawesome/free-solid-svg-icons';
import { version, instanceName } from '@client/config';
import FormLink from '@client/components/form/link.vue';
import FormBase from '@client/components/form/base.vue';
@@ -62,12 +61,11 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.instanceInfo,
- icon: faInfoCircle
+ icon: 'fas fa-info-circle'
},
version,
instanceName,
stats: null,
- faInfoCircle
}
},
diff --git a/src/client/pages/advanced-theme-editor.vue b/src/client/pages/advanced-theme-editor.vue
index fff525a32d..b40d9808ca 100644
--- a/src/client/pages/advanced-theme-editor.vue
+++ b/src/client/pages/advanced-theme-editor.vue
@@ -34,7 +34,7 @@
</div>
<div>
<div class="type" @click="chooseType($event, i)">
- {{ getTypeOf(v) }} <Fa :icon="faChevronDown"/>
+ {{ getTypeOf(v) }} <i class="fas fa-chevron-down"></i>
</div>
<!-- default -->
<div v-if="v === null" v-text="baseProps[k]" class="default-value" />
@@ -92,7 +92,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPalette, faChevronDown, faKeyboard } from '@fortawesome/free-solid-svg-icons';
import * as JSON5 from 'json5';
import { toUnicode } from 'punycode/';
@@ -125,7 +124,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.themeEditor,
- icon: faPalette,
+ icon: 'fas fa-palette',
},
theme: [] as ThemeViewModel,
name: '',
@@ -135,7 +134,6 @@ export default defineComponent({
themeToImport: '',
changed: false,
lightTheme, darkTheme, themeProps,
- faPalette, faChevronDown, faKeyboard,
}
},
diff --git a/src/client/pages/announcements.vue b/src/client/pages/announcements.vue
index 4e5f0e7f9c..a7ccb03588 100644
--- a/src/client/pages/announcements.vue
+++ b/src/client/pages/announcements.vue
@@ -8,7 +8,7 @@
<img v-if="announcement.imageUrl" :src="announcement.imageUrl"/>
</div>
<div class="_footer" v-if="$i && !announcement.isRead">
- <MkButton @click="read(items, announcement, i)" primary><Fa :icon="faCheck"/> {{ $ts.gotIt }}</MkButton>
+ <MkButton @click="read(items, announcement, i)" primary><i class="fas fa-check"></i> {{ $ts.gotIt }}</MkButton>
</div>
</section>
</MkPagination>
@@ -17,7 +17,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faCheck, faBroadcastTower } from '@fortawesome/free-solid-svg-icons';
import MkPagination from '@client/components/ui/pagination.vue';
import MkButton from '@client/components/ui/button.vue';
import * as os from '@client/os';
@@ -33,13 +32,12 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.announcements,
- icon: faBroadcastTower
+ icon: 'fas fa-broadcast-tower'
},
pagination: {
endpoint: 'announcements',
limit: 10,
},
- faCheck,
};
},
diff --git a/src/client/pages/api-console.vue b/src/client/pages/api-console.vue
index 669e814778..b153d10396 100644
--- a/src/client/pages/api-console.vue
+++ b/src/client/pages/api-console.vue
@@ -12,7 +12,7 @@
</MkSwitch>
<MkButton primary full @click="send" :disabled="sending">
<template v-if="sending"><MkEllipsis/></template>
- <template v-else><Fa :icon="faPaperPlane"/> Send</template>
+ <template v-else><i class="fas fa-paper-plane"></i> Send</template>
</MkButton>
</div>
<div v-if="res" class="_block" style="padding: 24px;">
@@ -25,7 +25,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faTerminal, faPaperPlane } from '@fortawesome/free-solid-svg-icons';
import * as JSON5 from 'json5';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
@@ -43,7 +42,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: 'API console',
- icon: faTerminal
+ icon: 'fas fa-terminal'
},
endpoint: '',
@@ -53,7 +52,6 @@ export default defineComponent({
endpoints: [],
withCredential: true,
- faPaperPlane
};
},
diff --git a/src/client/pages/channel-editor.vue b/src/client/pages/channel-editor.vue
index 7216aaec4a..bc772d34fa 100644
--- a/src/client/pages/channel-editor.vue
+++ b/src/client/pages/channel-editor.vue
@@ -7,15 +7,15 @@
<MkTextarea v-model:value="description">{{ $ts.description }}</MkTextarea>
<div class="banner">
- <MkButton v-if="bannerId == null" @click="setBannerImage"><Fa :icon="faPlus"/> {{ $ts._channel.setBanner }}</MkButton>
+ <MkButton v-if="bannerId == null" @click="setBannerImage"><i class="fas fa-plus"></i> {{ $ts._channel.setBanner }}</MkButton>
<div v-else-if="bannerUrl">
<img :src="bannerUrl" style="width: 100%;"/>
- <MkButton @click="removeBannerImage()"><Fa :icon="faTrashAlt"/> {{ $ts._channel.removeBanner }}</MkButton>
+ <MkButton @click="removeBannerImage()"><i class="fas fa-trash-alt"></i> {{ $ts._channel.removeBanner }}</MkButton>
</div>
</div>
</div>
<div class="_footer">
- <MkButton @click="save()" primary><Fa :icon="faSave"/> {{ channelId ? $ts.save : $ts.create }}</MkButton>
+ <MkButton @click="save()" primary><i class="fas fa-save"></i> {{ channelId ? $ts.save : $ts.create }}</MkButton>
</div>
</div>
</div>
@@ -23,8 +23,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faPlus, faSatelliteDish } from '@fortawesome/free-solid-svg-icons';
-import { faSave, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import MkTextarea from '@client/components/ui/textarea.vue';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
@@ -48,17 +46,16 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: computed(() => this.channelId ? {
title: this.$ts._channel.edit,
- icon: faSatelliteDish,
+ icon: 'fas fa-satellite-dish',
} : {
title: this.$ts._channel.create,
- icon: faSatelliteDish,
+ icon: 'fas fa-satellite-dish',
}),
channel: null,
name: null,
description: null,
bannerUrl: null,
bannerId: null,
- faSave, faTrashAlt, faPlus,faSatelliteDish,
};
},
diff --git a/src/client/pages/channel.vue b/src/client/pages/channel.vue
index f98bb41a38..1504264af5 100644
--- a/src/client/pages/channel.vue
+++ b/src/client/pages/channel.vue
@@ -3,15 +3,15 @@
<div class="wpgynlbz _content _panel _gap" :class="{ hide: !showBanner }">
<XChannelFollowButton :channel="channel" :full="true" class="subscribe"/>
<button class="_button toggle" @click="() => showBanner = !showBanner">
- <template v-if="showBanner"><Fa :icon="faAngleUp"/></template>
- <template v-else><Fa :icon="faAngleDown"/></template>
+ <template v-if="showBanner"><i class="fas fa-angle-up"></i></template>
+ <template v-else><i class="fas fa-angle-down"></i></template>
</button>
<div class="hideOverlay" v-if="!showBanner">
</div>
<div :style="{ backgroundImage: channel.bannerUrl ? `url(${channel.bannerUrl})` : null }" class="banner">
<div class="status">
- <div><Fa :icon="faUsers" fixed-width/><I18n :src="$ts._channel.usersCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.usersCount }}</b></template></I18n></div>
- <div><Fa :icon="faPencilAlt" fixed-width/><I18n :src="$ts._channel.notesCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.notesCount }}</b></template></I18n></div>
+ <div><i class="fas fa-users fa-fw"></i><I18n :src="$ts._channel.usersCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.usersCount }}</b></template></I18n></div>
+ <div><i class="fas fa-pencil-alt fa-fw"></i><I18n :src="$ts._channel.notesCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.notesCount }}</b></template></I18n></div>
</div>
<div class="fade"></div>
</div>
@@ -28,8 +28,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faSatelliteDish, faUsers, faPencilAlt, faAngleUp, faAngleDown } from '@fortawesome/free-solid-svg-icons';
-import { } from '@fortawesome/free-regular-svg-icons';
import MkContainer from '@client/components/ui/container.vue';
import XPostForm from '@client/components/post-form.vue';
import XTimeline from '@client/components/timeline.vue';
@@ -56,7 +54,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: computed(() => this.channel ? {
title: this.channel.name,
- icon: faSatelliteDish,
+ icon: 'fas fa-satellite-dish',
} : null),
channel: null,
showBanner: true,
@@ -67,7 +65,6 @@ export default defineComponent({
channelId: this.channelId,
})
},
- faSatelliteDish, faUsers, faPencilAlt, faAngleUp, faAngleDown,
};
},
@@ -111,7 +108,7 @@ export default defineComponent({
background: rgba(0, 0, 0, 0.5);
border-radius: 100%;
- > [data-icon] {
+ > i {
vertical-align: middle;
}
}
diff --git a/src/client/pages/channels.vue b/src/client/pages/channels.vue
index ebf1e7b871..7e3302959b 100644
--- a/src/client/pages/channels.vue
+++ b/src/client/pages/channels.vue
@@ -2,9 +2,9 @@
<div>
<div class="_section" style="padding: 0;" v-if="$i">
<MkTab class="_content" v-model:value="tab">
- <option value="featured"><Fa :icon="faFireAlt"/> {{ $ts._channel.featured }}</option>
- <option value="following"><Fa :icon="faHeart"/> {{ $ts._channel.following }}</option>
- <option value="owned"><Fa :icon="faEdit"/> {{ $ts._channel.owned }}</option>
+ <option value="featured"><i class="fas fa-fire-alt"></i> {{ $ts._channel.featured }}</option>
+ <option value="following"><i class="fas fa-heart"></i> {{ $ts._channel.following }}</option>
+ <option value="owned"><i class="fas fa-edit"></i> {{ $ts._channel.owned }}</option>
</MkTab>
</div>
@@ -22,7 +22,7 @@
</div>
<div class="_content grwlizim owned" v-if="tab === 'owned'">
- <MkButton class="new" @click="create()"><Fa :icon="faPlus"/></MkButton>
+ <MkButton class="new" @click="create()"><i class="fas fa-plus"></i></MkButton>
<MkPagination :pagination="ownedPagination" #default="{items}">
<MkChannelPreview v-for="channel in items" class="_gap" :channel="channel" :key="channel.id"/>
</MkPagination>
@@ -33,8 +33,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faSatelliteDish, faPlus, faEdit, faFireAlt } from '@fortawesome/free-solid-svg-icons';
-import { faHeart } from '@fortawesome/free-regular-svg-icons';
import MkChannelPreview from '@client/components/channel-preview.vue';
import MkPagination from '@client/components/ui/pagination.vue';
import MkButton from '@client/components/ui/button.vue';
@@ -49,9 +47,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.channel,
- icon: faSatelliteDish,
+ icon: 'fas fa-satellite-dish',
action: {
- icon: faPlus,
+ icon: 'fas fa-plus',
handler: this.create
}
},
@@ -68,7 +66,6 @@ export default defineComponent({
endpoint: 'channels/owned',
limit: 5,
},
- faSatelliteDish, faPlus, faEdit, faHeart, faFireAlt
};
},
methods: {
diff --git a/src/client/pages/clip.vue b/src/client/pages/clip.vue
index ca3e051d51..8777975557 100644
--- a/src/client/pages/clip.vue
+++ b/src/client/pages/clip.vue
@@ -15,7 +15,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faEllipsisH, faPaperclip, faPencilAlt, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import MkContainer from '@client/components/ui/container.vue';
import XPostForm from '@client/components/post-form.vue';
import XNotes from '@client/components/notes.vue';
@@ -40,9 +39,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: computed(() => this.clip ? {
title: this.clip.name,
- icon: faPaperclip,
+ icon: 'fas fa-paperclip',
action: {
- icon: faEllipsisH,
+ icon: 'fas fa-ellipsis-h',
handler: this.menu
}
} : null),
@@ -81,7 +80,7 @@ export default defineComponent({
methods: {
menu(ev) {
os.modalMenu([this.isOwned ? {
- icon: faPencilAlt,
+ icon: 'fas fa-pencil-alt',
text: this.$ts.edit,
action: async () => {
const { canceled, result } = await os.form(this.clip.name, {
@@ -111,7 +110,7 @@ export default defineComponent({
});
}
} : undefined, this.isOwned ? {
- icon: faTrashAlt,
+ icon: 'fas fa-trash-alt',
text: this.$ts.delete,
danger: true,
action: async () => {
diff --git a/src/client/pages/doc.vue b/src/client/pages/doc.vue
index cf3628dafb..a4cf25033e 100644
--- a/src/client/pages/doc.vue
+++ b/src/client/pages/doc.vue
@@ -10,7 +10,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons'
import MarkdownIt from 'markdown-it';
import MarkdownItAnchor from 'markdown-it-anchor';
import { url, lang } from '@client/config';
@@ -41,7 +40,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: computed(() => this.title ? {
title: this.title,
- icon: faQuestionCircle,
+ icon: 'fas fa-question-circle',
} : null),
title: null,
body: null,
diff --git a/src/client/pages/docs.vue b/src/client/pages/docs.vue
index 92eab86716..e51528f83d 100644
--- a/src/client/pages/docs.vue
+++ b/src/client/pages/docs.vue
@@ -14,7 +14,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons'
import { url, lang } from '@client/config';
import * as symbols from '@client/symbols';
@@ -23,10 +22,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.help,
- icon: faQuestionCircle
+ icon: 'fas fa-question-circle'
},
docs: [],
- faQuestionCircle
}
},
diff --git a/src/client/pages/drive.vue b/src/client/pages/drive.vue
index 33bbfbc50f..753114f725 100644
--- a/src/client/pages/drive.vue
+++ b/src/client/pages/drive.vue
@@ -6,7 +6,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faCloud } from '@fortawesome/free-solid-svg-icons';
import XDrive from '@client/components/drive.vue';
import * as os from '@client/os';
import * as symbols from '@client/symbols';
@@ -20,7 +19,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: computed(() => this.folder ? this.folder.name : this.$ts.drive),
- icon: faCloud,
+ icon: 'fas fa-cloud',
menu: () => this.$refs.drive.getMenu()
},
folder: null,
diff --git a/src/client/pages/explore.vue b/src/client/pages/explore.vue
index dc0803237b..7bcb09d8c5 100644
--- a/src/client/pages/explore.vue
+++ b/src/client/pages/explore.vue
@@ -2,7 +2,7 @@
<div class="lznhrdub _root">
<div>
<div class="_isolated">
- <MkInput v-model:value="query" :debounce="true" type="search"><template #icon><Fa :icon="faSearch"/></template><span>{{ $ts.searchUser }}</span></MkInput>
+ <MkInput v-model:value="query" :debounce="true" type="search"><template #icon><i class="fas fa-search"></i></template><span>{{ $ts.searchUser }}</span></MkInput>
</div>
<XUserList v-if="query" class="_gap" :pagination="searchPagination" ref="search"/>
@@ -14,19 +14,19 @@
<template v-if="tag == null">
<MkFolder class="_gap" persist-key="explore-pinned-users">
- <template #header><Fa :icon="faBookmark" fixed-width style="margin-right: 0.5em;"/>{{ $ts.pinnedUsers }}</template>
+ <template #header><i class="fas fa-bookmark fa-fw" style="margin-right: 0.5em;"></i>{{ $ts.pinnedUsers }}</template>
<XUserList :pagination="pinnedUsers"/>
</MkFolder>
<MkFolder class="_gap" persist-key="explore-popular-users">
- <template #header><Fa :icon="faChartLine" fixed-width style="margin-right: 0.5em;"/>{{ $ts.popularUsers }}</template>
+ <template #header><i class="fas fa-chart-line fa-fw" style="margin-right: 0.5em;"></i>{{ $ts.popularUsers }}</template>
<XUserList :pagination="popularUsers"/>
</MkFolder>
<MkFolder class="_gap" persist-key="explore-recently-updated-users">
- <template #header><Fa :icon="faCommentAlt" fixed-width style="margin-right: 0.5em;"/>{{ $ts.recentlyUpdatedUsers }}</template>
+ <template #header><i class="fas fa-comment-alt fa-fw" style="margin-right: 0.5em;"></i>{{ $ts.recentlyUpdatedUsers }}</template>
<XUserList :pagination="recentlyUpdatedUsers"/>
</MkFolder>
<MkFolder class="_gap" persist-key="explore-recently-registered-users">
- <template #header><Fa :icon="faPlus" fixed-width style="margin-right: 0.5em;"/>{{ $ts.recentlyRegisteredUsers }}</template>
+ <template #header><i class="fas fa-plus fa-fw" style="margin-right: 0.5em;"></i>{{ $ts.recentlyRegisteredUsers }}</template>
<XUserList :pagination="recentlyRegisteredUsers"/>
</MkFolder>
</template>
@@ -37,7 +37,7 @@
</div>
<MkFolder :foldable="true" :expanded="false" ref="tags" class="_gap">
- <template #header><Fa :icon="faHashtag" fixed-width style="margin-right: 0.5em;"/>{{ $ts.popularTags }}</template>
+ <template #header><i class="fas fa-hashtag fa-fw" style="margin-right: 0.5em;"></i>{{ $ts.popularTags }}</template>
<div class="vxjfqztj">
<MkA v-for="tag in tagsLocal" :to="`/explore/tags/${tag.tag}`" :key="'local:' + tag.tag" class="local">{{ tag.tag }}</MkA>
@@ -46,21 +46,21 @@
</MkFolder>
<MkFolder v-if="tag != null" :key="`${tag}`" class="_gap">
- <template #header><Fa :icon="faHashtag" fixed-width style="margin-right: 0.5em;"/>{{ tag }}</template>
+ <template #header><i class="fas fa-hashtag fa-fw" style="margin-right: 0.5em;"></i>{{ tag }}</template>
<XUserList :pagination="tagUsers"/>
</MkFolder>
<template v-if="tag == null">
<MkFolder class="_gap">
- <template #header><Fa :icon="faChartLine" fixed-width style="margin-right: 0.5em;"/>{{ $ts.popularUsers }}</template>
+ <template #header><i class="fas fa-chart-line fa-fw" style="margin-right: 0.5em;"></i>{{ $ts.popularUsers }}</template>
<XUserList :pagination="popularUsersF"/>
</MkFolder>
<MkFolder class="_gap">
- <template #header><Fa :icon="faCommentAlt" fixed-width style="margin-right: 0.5em;"/>{{ $ts.recentlyUpdatedUsers }}</template>
+ <template #header><i class="fas fa-comment-alt fa-fw" style="margin-right: 0.5em;"></i>{{ $ts.recentlyUpdatedUsers }}</template>
<XUserList :pagination="recentlyUpdatedUsersF"/>
</MkFolder>
<MkFolder class="_gap">
- <template #header><Fa :icon="faRocket" fixed-width style="margin-right: 0.5em;"/>{{ $ts.recentlyDiscoveredUsers }}</template>
+ <template #header><i class="fas fa-rocket fa-fw" style="margin-right: 0.5em;"></i>{{ $ts.recentlyDiscoveredUsers }}</template>
<XUserList :pagination="recentlyRegisteredUsersF"/>
</MkFolder>
</template>
@@ -70,8 +70,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faChartLine, faPlus, faHashtag, faRocket, faSearch } from '@fortawesome/free-solid-svg-icons';
-import { faBookmark, faCommentAlt } from '@fortawesome/free-regular-svg-icons';
import XUserList from '@client/components/user-list.vue';
import MkFolder from '@client/components/ui/folder.vue';
import MkInput from '@client/components/ui/input.vue';
@@ -97,7 +95,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.explore,
- icon: faHashtag
+ icon: 'fas fa-hashtag'
},
pinnedUsers: { endpoint: 'pinned-users' },
popularUsers: { endpoint: 'users', limit: 10, noPaging: true, params: {
@@ -139,7 +137,6 @@ export default defineComponent({
stats: null,
query: null,
num: number,
- faBookmark, faChartLine, faCommentAlt, faPlus, faHashtag, faRocket, faSearch,
};
},
diff --git a/src/client/pages/favorites.vue b/src/client/pages/favorites.vue
index 7ecd327137..408ab222b5 100644
--- a/src/client/pages/favorites.vue
+++ b/src/client/pages/favorites.vue
@@ -6,7 +6,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faStar } from '@fortawesome/free-solid-svg-icons';
import Progress from '@client/scripts/loading';
import XNotes from '@client/components/notes.vue';
import * as os from '@client/os';
@@ -21,7 +20,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.favorites,
- icon: faStar
+ icon: 'fas fa-star'
},
pagination: {
endpoint: 'i/favorites',
diff --git a/src/client/pages/featured.vue b/src/client/pages/featured.vue
index cd7343f583..21818ba617 100644
--- a/src/client/pages/featured.vue
+++ b/src/client/pages/featured.vue
@@ -6,7 +6,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faFireAlt } from '@fortawesome/free-solid-svg-icons';
import Progress from '@client/scripts/loading';
import XNotes from '@client/components/notes.vue';
import * as symbols from '@client/symbols';
@@ -20,14 +19,13 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.featured,
- icon: faFireAlt
+ icon: 'fas fa-fire-alt'
},
pagination: {
endpoint: 'notes/featured',
limit: 10,
offsetMode: true
},
- faFireAlt
};
},
diff --git a/src/client/pages/follow-requests.vue b/src/client/pages/follow-requests.vue
index 31c00d63cd..9f27a6baa8 100644
--- a/src/client/pages/follow-requests.vue
+++ b/src/client/pages/follow-requests.vue
@@ -19,8 +19,8 @@
<Mfm :text="req.follower.description" :is-note="false" :author="req.follower" :i="$i" :custom-emojis="req.follower.emojis" :plain="true" :nowrap="true"/>
</div>
<div class="actions">
- <button class="_button" @click="accept(req.follower)"><Fa :icon="faCheck"/></button>
- <button class="_button" @click="reject(req.follower)"><Fa :icon="faTimes"/></button>
+ <button class="_button" @click="accept(req.follower)"><i class="fas fa-check"></i></button>
+ <button class="_button" @click="reject(req.follower)"><i class="fas fa-times"></i></button>
</div>
</div>
</div>
@@ -31,7 +31,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faUserClock, faCheck, faTimes } from '@fortawesome/free-solid-svg-icons';
import MkPagination from '@client/components/ui/pagination.vue';
import { userPage, acct } from '../filters/user';
import * as os from '@client/os';
@@ -46,13 +45,12 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.followRequests,
- icon: faUserClock,
+ icon: 'fas fa-user-clock',
},
pagination: {
endpoint: 'following/requests/list',
limit: 10,
},
- faCheck, faTimes, faUserClock
};
},
diff --git a/src/client/pages/instance-info.vue b/src/client/pages/instance-info.vue
index a3cd402993..662b82ddb1 100644
--- a/src/client/pages/instance-info.vue
+++ b/src/client/pages/instance-info.vue
@@ -99,9 +99,12 @@
<span>Raw</span>
</FormObjectView>
<FormGroup>
+ <template #label>Well-known resources</template>
<FormLink :to="`https://${host}/.well-known/host-meta`" external>host-meta</FormLink>
<FormLink :to="`https://${host}/.well-known/host-meta.json`" external>host-meta.json</FormLink>
<FormLink :to="`https://${host}/.well-known/nodeinfo`" external>nodeinfo</FormLink>
+ <FormLink :to="`https://${host}/robots.txt`" external>robots.txt</FormLink>
+ <FormLink :to="`https://${host}/manifest.json`" external>manifest.json</FormLink>
</FormGroup>
<FormSuspense :p="dnsPromiseFactory" v-slot="{ result: dns }">
<FormGroup>
@@ -130,7 +133,6 @@
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
-import { faExternalLinkAlt, faInfoCircle } from '@fortawesome/free-solid-svg-icons';
import Chart from 'chart.js';
import FormObjectView from '@client/components/form/object-view.vue';
import FormTextarea from '@client/components/form/textarea.vue';
@@ -182,10 +184,10 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.instanceInfo,
- icon: faInfoCircle,
+ icon: 'fas fa-info-circle',
actions: [{
text: `https://${this.host}`,
- icon: faExternalLinkAlt,
+ icon: 'fas fa-external-link-alt',
handler: () => {
window.open(`https://${this.host}`, '_blank');
}
diff --git a/src/client/pages/instance/abuses.vue b/src/client/pages/instance/abuses.vue
index c8355b0683..73196027dc 100644
--- a/src/client/pages/instance/abuses.vue
+++ b/src/client/pages/instance/abuses.vue
@@ -1,5 +1,5 @@
<template>
-<div class="">
+<div class="lcixvhis">
<div class="_section reports">
<div class="_content">
<div class="inputs" style="display: flex;">
@@ -63,8 +63,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPlus, faUsers, faSearch, faBookmark, faMicrophoneSlash, faExclamationCircle } from '@fortawesome/free-solid-svg-icons';
-import { faSnowflake, faBookmark as farBookmark } from '@fortawesome/free-regular-svg-icons';
import parseAcct from '@/misc/acct/parse';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
@@ -82,11 +80,13 @@ export default defineComponent({
MkPagination,
},
+ emits: ['info'],
+
data() {
return {
[symbols.PAGE_INFO]: {
title: this.$ts.abuseReports,
- icon: faExclamationCircle
+ icon: 'fas fa-exclamation-circle'
},
searchUsername: '',
searchHost: '',
@@ -102,7 +102,6 @@ export default defineComponent({
targetUserOrigin: this.targetUserOrigin,
}),
},
- faPlus, faUsers, faSearch, faBookmark, farBookmark, faMicrophoneSlash, faSnowflake
}
},
@@ -120,6 +119,10 @@ export default defineComponent({
},
},
+ mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
methods: {
acct,
@@ -135,6 +138,10 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
+.lcixvhis {
+ margin: var(--margin);
+}
+
.bcekxzvu {
> .target {
display: flex;
diff --git a/src/client/pages/instance/announcements.vue b/src/client/pages/instance/announcements.vue
index f9d58a29c4..ac0e9d5135 100644
--- a/src/client/pages/instance/announcements.vue
+++ b/src/client/pages/instance/announcements.vue
@@ -1,35 +1,29 @@
<template>
<div class="ztgjmzrw">
- <div class="_section">
- <div class="_content">
- <MkButton @click="add()" primary style="margin: 0 auto 16px auto;"><Fa :icon="faPlus"/> {{ $ts.add }}</MkButton>
- <section class="_card _gap announcements" v-for="announcement in announcements">
- <div class="_content announcement">
- <MkInput v-model:value="announcement.title">
- <span>{{ $ts.title }}</span>
- </MkInput>
- <MkTextarea v-model:value="announcement.text">
- <span>{{ $ts.text }}</span>
- </MkTextarea>
- <MkInput v-model:value="announcement.imageUrl">
- <span>{{ $ts.imageUrl }}</span>
- </MkInput>
- <p v-if="announcement.reads">{{ $t('nUsersRead', { n: announcement.reads }) }}</p>
- <div class="buttons">
- <MkButton class="button" inline @click="save(announcement)" primary><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- <MkButton class="button" inline @click="remove(announcement)"><Fa :icon="faTrashAlt"/> {{ $ts.remove }}</MkButton>
- </div>
- </div>
- </section>
+ <MkButton @click="add()" primary style="margin: 0 auto 16px auto;"><i class="fas fa-plus"></i> {{ $ts.add }}</MkButton>
+ <section class="_card _gap announcements" v-for="announcement in announcements">
+ <div class="_content announcement">
+ <MkInput v-model:value="announcement.title">
+ <span>{{ $ts.title }}</span>
+ </MkInput>
+ <MkTextarea v-model:value="announcement.text">
+ <span>{{ $ts.text }}</span>
+ </MkTextarea>
+ <MkInput v-model:value="announcement.imageUrl">
+ <span>{{ $ts.imageUrl }}</span>
+ </MkInput>
+ <p v-if="announcement.reads">{{ $t('nUsersRead', { n: announcement.reads }) }}</p>
+ <div class="buttons">
+ <MkButton class="button" inline @click="save(announcement)" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
+ <MkButton class="button" inline @click="remove(announcement)"><i class="fas fa-trash-alt"></i> {{ $ts.remove }}</MkButton>
+ </div>
</div>
- </div>
+ </section>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faBroadcastTower, faPlus } from '@fortawesome/free-solid-svg-icons';
-import { faSave, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
import MkTextarea from '@client/components/ui/textarea.vue';
@@ -43,14 +37,15 @@ export default defineComponent({
MkTextarea,
},
+ emits: ['info'],
+
data() {
return {
[symbols.PAGE_INFO]: {
title: this.$ts.announcements,
- icon: faBroadcastTower
+ icon: 'fas fa-broadcast-tower'
},
announcements: [],
- faBroadcastTower, faSave, faTrashAlt, faPlus
}
},
@@ -60,6 +55,10 @@ export default defineComponent({
});
},
+ mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
methods: {
add() {
this.announcements.unshift({
@@ -112,3 +111,9 @@ export default defineComponent({
}
});
</script>
+
+<style lang="scss" scoped>
+.ztgjmzrw {
+ margin: var(--margin);
+}
+</style>
diff --git a/src/client/pages/instance/bot-protection.vue b/src/client/pages/instance/bot-protection.vue
new file mode 100644
index 0000000000..449b8a233d
--- /dev/null
+++ b/src/client/pages/instance/bot-protection.vue
@@ -0,0 +1,138 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormRadios v-model="provider">
+ <template #desc><i class="fas fa-shield-alt"></i> {{ $ts.botProtection }}</template>
+ <option :value="null">{{ $ts.none }} ({{ $ts.notRecommended }})</option>
+ <option value="hcaptcha">hCaptcha</option>
+ <option value="recaptcha">reCAPTCHA</option>
+ </FormRadios>
+
+ <template v-if="provider === 'hcaptcha'">
+ <div class="_formItem _formNoConcat" v-sticky-container>
+ <div class="_formLabel">hCaptcha</div>
+ <div class="main">
+ <FormInput v-model:value="hcaptchaSiteKey">
+ <template #prefix><i class="fas fa-key"></i></template>
+ <span>{{ $ts.hcaptchaSiteKey }}</span>
+ </FormInput>
+ <FormInput v-model:value="hcaptchaSecretKey">
+ <template #prefix><i class="fas fa-key"></i></template>
+ <span>{{ $ts.hcaptchaSecretKey }}</span>
+ </FormInput>
+ </div>
+ </div>
+ <div class="_formItem _formNoConcat" v-sticky-container>
+ <div class="_formLabel">{{ $ts.preview }}</div>
+ <div class="_formPanel" style="padding: var(--formContentHMargin);">
+ <MkCaptcha provider="hcaptcha" :sitekey="hcaptchaSiteKey || '10000000-ffff-ffff-ffff-000000000001'"/>
+ </div>
+ </div>
+ </template>
+ <template v-else-if="provider === 'recaptcha'">
+ <div class="_formItem _formNoConcat" v-sticky-container>
+ <div class="_formLabel">reCAPTCHA</div>
+ <div class="main">
+ <FormInput v-model:value="recaptchaSiteKey">
+ <template #prefix><i class="fas fa-key"></i></template>
+ <span>{{ $ts.recaptchaSiteKey }}</span>
+ </FormInput>
+ <FormInput v-model:value="recaptchaSecretKey">
+ <template #prefix><i class="fas fa-key"></i></template>
+ <span>{{ $ts.recaptchaSecretKey }}</span>
+ </FormInput>
+ </div>
+ </div>
+ <div v-if="recaptchaSiteKey" class="_formItem _formNoConcat" v-sticky-container>
+ <div class="_formLabel">{{ $ts.preview }}</div>
+ <div class="_formPanel" style="padding: var(--formContentHMargin);">
+ <MkCaptcha provider="recaptcha" :sitekey="recaptchaSiteKey"/>
+ </div>
+ </div>
+ </template>
+
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineAsyncComponent, defineComponent } from 'vue';
+import FormRadios from '@client/components/form/radios.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormInfo from '@client/components/form/info.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormRadios,
+ FormInput,
+ FormBase,
+ FormGroup,
+ FormButton,
+ FormInfo,
+ FormSuspense,
+ MkCaptcha: defineAsyncComponent(() => import('@client/components/captcha.vue')),
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.botProtection,
+ icon: 'fas fa-shield-alt'
+ },
+ provider: null,
+ enableHcaptcha: false,
+ hcaptchaSiteKey: null,
+ hcaptchaSecretKey: null,
+ enableRecaptcha: false,
+ recaptchaSiteKey: null,
+ recaptchaSecretKey: null,
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.enableHcaptcha = meta.enableHcaptcha;
+ this.hcaptchaSiteKey = meta.hcaptchaSiteKey;
+ this.hcaptchaSecretKey = meta.hcaptchaSecretKey;
+ this.enableRecaptcha = meta.enableRecaptcha;
+ this.recaptchaSiteKey = meta.recaptchaSiteKey;
+ this.recaptchaSecretKey = meta.recaptchaSecretKey;
+
+ this.provider = this.enableHcaptcha ? 'hcaptcha' : this.enableRecaptcha ? 'recaptcha' : null;
+
+ this.$watch(() => this.provider, () => {
+ this.enableHcaptcha = this.provider === 'hcaptcha';
+ this.enableRecaptcha = this.provider === 'recaptcha';
+ });
+ },
+
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ enableHcaptcha: this.enableHcaptcha,
+ hcaptchaSiteKey: this.hcaptchaSiteKey,
+ hcaptchaSecretKey: this.hcaptchaSecretKey,
+ enableRecaptcha: this.enableRecaptcha,
+ recaptchaSiteKey: this.recaptchaSiteKey,
+ recaptchaSecretKey: this.recaptchaSecretKey,
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/database.vue b/src/client/pages/instance/database.vue
new file mode 100644
index 0000000000..a41d61ce2b
--- /dev/null
+++ b/src/client/pages/instance/database.vue
@@ -0,0 +1,60 @@
+<template>
+<FormBase>
+ <FormSuspense :p="databasePromiseFactory" v-slot="{ result: database }">
+ <FormGroup v-for="table in database" :key="table[0]">
+ <template #label>{{ table[0] }}</template>
+ <FormKeyValueView>
+ <template #key>Size</template>
+ <template #value>{{ bytes(table[1].size) }}</template>
+ </FormKeyValueView>
+ <FormKeyValueView>
+ <template #key>Records</template>
+ <template #value>{{ number(table[1].count) }}</template>
+ </FormKeyValueView>
+ </FormGroup>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import FormKeyValueView from '@client/components/form/key-value-view.vue';
+import FormLink from '@client/components/form/link.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import bytes from '@client/filters/bytes';
+import number from '@client/filters/number';
+
+export default defineComponent({
+ components: {
+ FormSuspense,
+ FormKeyValueView,
+ FormBase,
+ FormGroup,
+ FormLink,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.database,
+ icon: 'fas fa-database'
+ },
+ databasePromiseFactory: () => os.api('admin/get-table-stats', {}).then(res => Object.entries(res).sort((a, b) => b[1].size - a[1].size)),
+ }
+ },
+
+ mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ bytes, number,
+ }
+});
+</script>
diff --git a/src/client/pages/instance/email-settings.vue b/src/client/pages/instance/email-settings.vue
new file mode 100644
index 0000000000..9965a1420f
--- /dev/null
+++ b/src/client/pages/instance/email-settings.vue
@@ -0,0 +1,127 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormSwitch v-model:value="enableEmail">{{ $ts.enableEmail }}<template #desc>{{ $ts.emailConfigInfo }}</template></FormSwitch>
+
+ <template v-if="enableEmail">
+ <FormInput v-model:value="email" type="email">
+ <span>{{ $ts.emailAddress }}</span>
+ </FormInput>
+
+ <div class="_formItem _formNoConcat" v-sticky-container>
+ <div class="_formLabel">{{ $ts.smtpConfig }}</div>
+ <div class="main">
+ <FormInput v-model:value="smtpHost">
+ <span>{{ $ts.smtpHost }}</span>
+ </FormInput>
+ <FormInput v-model:value="smtpPort" type="number">
+ <span>{{ $ts.smtpPort }}</span>
+ </FormInput>
+ <FormInput v-model:value="smtpUser">
+ <span>{{ $ts.smtpUser }}</span>
+ </FormInput>
+ <FormInput v-model:value="smtpPass" type="password">
+ <span>{{ $ts.smtpPass }}</span>
+ </FormInput>
+ <FormInfo>{{ $ts.emptyToDisableSmtpAuth }}</FormInfo>
+ <FormSwitch v-model:value="smtpSecure">{{ $ts.smtpSecure }}<template #desc>{{ $ts.smtpSecureInfo }}</template></FormSwitch>
+ </div>
+ </div>
+
+ <FormButton @click="testEmail">{{ $ts.testEmail }}</FormButton>
+ </template>
+
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormSwitch from '@client/components/form/switch.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormInfo from '@client/components/form/info.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormSwitch,
+ FormInput,
+ FormBase,
+ FormGroup,
+ FormButton,
+ FormInfo,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.emailServer,
+ icon: 'fas fa-envelope'
+ },
+ enableEmail: false,
+ email: null,
+ smtpSecure: false,
+ smtpHost: '',
+ smtpPort: 0,
+ smtpUser: '',
+ smtpPass: '',
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.enableEmail = meta.enableEmail;
+ this.email = meta.email;
+ this.smtpSecure = meta.smtpSecure;
+ this.smtpHost = meta.smtpHost;
+ this.smtpPort = meta.smtpPort;
+ this.smtpUser = meta.smtpUser;
+ this.smtpPass = meta.smtpPass;
+ },
+
+ async testEmail() {
+ const { canceled, result: destination } = await os.dialog({
+ title: this.$ts.destination,
+ input: {
+ placeholder: this.$instance.maintainerEmail
+ }
+ });
+ if (canceled) return;
+ os.apiWithDialog('admin/send-email', {
+ to: destination,
+ subject: 'Test email',
+ text: 'Yo'
+ });
+ },
+
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ enableEmail: this.enableEmail,
+ email: this.email,
+ smtpSecure: this.smtpSecure,
+ smtpHost: this.smtpHost,
+ smtpPort: this.smtpPort,
+ smtpUser: this.smtpUser,
+ smtpPass: this.smtpPass,
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/emoji-edit-dialog.vue b/src/client/pages/instance/emoji-edit-dialog.vue
index 34eca47b4e..f7a3671584 100644
--- a/src/client/pages/instance/emoji-edit-dialog.vue
+++ b/src/client/pages/instance/emoji-edit-dialog.vue
@@ -8,22 +8,23 @@
>
<template #header>:{{ emoji.name }}:</template>
- <div class="yigymqpb _section">
- <img :src="emoji.url" class="img"/>
- <MkInput v-model:value="name"><span>{{ $ts.name }}</span></MkInput>
- <MkInput v-model:value="category" :datalist="categories"><span>{{ $ts.category }}</span></MkInput>
- <MkInput v-model:value="aliases">
- <span>{{ $ts.tags }}</span>
- <template #desc>{{ $ts.setMultipleBySeparatingWithSpace }}</template>
- </MkInput>
- <MkButton danger @click="del()"><Fa :icon="faTrashAlt"/> {{ $ts.delete }}</MkButton>
+ <div class="_monolithic_">
+ <div class="yigymqpb _section">
+ <img :src="emoji.url" class="img"/>
+ <MkInput v-model:value="name"><span>{{ $ts.name }}</span></MkInput>
+ <MkInput v-model:value="category" :datalist="categories"><span>{{ $ts.category }}</span></MkInput>
+ <MkInput v-model:value="aliases">
+ <span>{{ $ts.tags }}</span>
+ <template #desc>{{ $ts.setMultipleBySeparatingWithSpace }}</template>
+ </MkInput>
+ <MkButton danger @click="del()"><i class="fas fa-trash-alt"></i> {{ $ts.delete }}</MkButton>
+ </div>
</div>
</XModalWindow>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import XModalWindow from '@client/components/ui/modal-window.vue';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
@@ -51,7 +52,6 @@ export default defineComponent({
category: this.emoji.category,
aliases: this.emoji.aliases?.join(' '),
categories: [],
- faTrashAlt,
}
},
diff --git a/src/client/pages/instance/emojis.vue b/src/client/pages/instance/emojis.vue
index 722ed0063f..fd641703cb 100644
--- a/src/client/pages/instance/emojis.vue
+++ b/src/client/pages/instance/emojis.vue
@@ -1,58 +1,52 @@
<template>
-<div class="mk-instance-emojis">
- <div class="_section" style="padding: 0;">
- <MkTab v-model:value="tab">
- <option value="local">{{ $ts.local }}</option>
- <option value="remote">{{ $ts.remote }}</option>
- </MkTab>
- </div>
+<div class="ogwlenmc">
+ <MkTab v-model:value="tab">
+ <option value="local">{{ $ts.local }}</option>
+ <option value="remote">{{ $ts.remote }}</option>
+ </MkTab>
- <div class="_section">
- <div class="local" v-if="tab === 'local'">
- <MkButton primary @click="add" style="margin: 0 auto var(--margin) auto;"><Fa :icon="faPlus"/> {{ $ts.addEmoji }}</MkButton>
- <MkInput v-model:value="query" :debounce="true" type="search"><template #icon><Fa :icon="faSearch"/></template><span>{{ $ts.search }}</span></MkInput>
- <MkPagination :pagination="pagination" ref="emojis">
- <template #empty><span>{{ $ts.noCustomEmojis }}</span></template>
- <template #default="{items}">
- <div class="emojis">
- <button class="emoji _panel _button" v-for="emoji in items" :key="emoji.id" @click="edit(emoji)">
- <img :src="emoji.url" class="img" :alt="emoji.name"/>
- <div class="body">
- <div class="name">{{ emoji.name }}</div>
- <div class="info">{{ emoji.category }}</div>
- </div>
- </button>
- </div>
- </template>
- </MkPagination>
- </div>
+ <div class="local" v-if="tab === 'local'">
+ <MkButton primary @click="add" style="margin: var(--margin) auto;"><i class="fas fa-plus"></i> {{ $ts.addEmoji }}</MkButton>
+ <MkInput v-model:value="query" :debounce="true" type="search" style="margin: var(--margin);"><template #icon><i class="fas fa-search"></i></template><span>{{ $ts.search }}</span></MkInput>
+ <MkPagination :pagination="pagination" ref="emojis">
+ <template #empty><span>{{ $ts.noCustomEmojis }}</span></template>
+ <template #default="{items}">
+ <div class="ldhfsamy">
+ <button class="emoji _panel _button" v-for="emoji in items" :key="emoji.id" @click="edit(emoji)">
+ <img :src="emoji.url" class="img" :alt="emoji.name"/>
+ <div class="body">
+ <div class="name _monospace">{{ emoji.name }}</div>
+ <div class="info">{{ emoji.category }}</div>
+ </div>
+ </button>
+ </div>
+ </template>
+ </MkPagination>
+ </div>
- <div class="remote" v-else-if="tab === 'remote'">
- <MkInput v-model:value="queryRemote" :debounce="true" type="search"><template #icon><Fa :icon="faSearch"/></template><span>{{ $ts.search }}</span></MkInput>
- <MkInput v-model:value="host" :debounce="true"><span>{{ $ts.host }}</span></MkInput>
- <MkPagination :pagination="remotePagination" ref="remoteEmojis">
- <template #empty><span>{{ $ts.noCustomEmojis }}</span></template>
- <template #default="{items}">
- <div class="emojis">
- <div class="emoji _panel _button" v-for="emoji in items" :key="emoji.id" @click="remoteMenu(emoji, $event)">
- <img :src="emoji.url" class="img" :alt="emoji.name"/>
- <div class="body">
- <div class="name">{{ emoji.name }}</div>
- <div class="info">{{ emoji.host }}</div>
- </div>
+ <div class="remote" v-else-if="tab === 'remote'">
+ <MkInput v-model:value="queryRemote" :debounce="true" type="search" style="margin: var(--margin);"><template #icon><i class="fas fa-search"></i></template><span>{{ $ts.search }}</span></MkInput>
+ <MkInput v-model:value="host" :debounce="true" style="margin: var(--margin);"><span>{{ $ts.host }}</span></MkInput>
+ <MkPagination :pagination="remotePagination" ref="remoteEmojis">
+ <template #empty><span>{{ $ts.noCustomEmojis }}</span></template>
+ <template #default="{items}">
+ <div class="ldhfsamy">
+ <div class="emoji _panel _button" v-for="emoji in items" :key="emoji.id" @click="remoteMenu(emoji, $event)">
+ <img :src="emoji.url" class="img" :alt="emoji.name"/>
+ <div class="body">
+ <div class="name _monospace">{{ emoji.name }}</div>
+ <div class="info">{{ emoji.host }}</div>
</div>
</div>
- </template>
- </MkPagination>
- </div>
+ </div>
+ </template>
+ </MkPagination>
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faPlus, faSave, faSearch } from '@fortawesome/free-solid-svg-icons';
-import { faTrashAlt, faLaugh } from '@fortawesome/free-regular-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
import MkPagination from '@client/components/ui/pagination.vue';
@@ -69,13 +63,15 @@ export default defineComponent({
MkPagination,
},
+ emits: ['info'],
+
data() {
return {
[symbols.PAGE_INFO]: {
title: this.$ts.customEmojis,
- icon: faLaugh,
+ icon: 'fas fa-laugh',
action: {
- icon: faPlus,
+ icon: 'fas fa-plus',
handler: this.add
}
},
@@ -98,10 +94,13 @@ export default defineComponent({
host: (this.host && this.host !== '') ? this.host : null
}))
},
- faTrashAlt, faPlus, faLaugh, faSave, faSearch,
}
},
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
methods: {
async add(e) {
const files = await selectFile(e.currentTarget || e.target, null, true);
@@ -144,7 +143,7 @@ export default defineComponent({
text: ':' + emoji.name + ':',
}, {
text: this.$ts.import,
- icon: faPlus,
+ icon: 'fas fa-plus',
action: () => { this.im(emoji) }
}], ev.currentTarget || ev.target);
}
@@ -153,85 +152,86 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
-.mk-instance-emojis {
- > ._section {
- > .local {
- .emojis {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
- grid-gap: var(--margin);
-
- > .emoji {
- display: flex;
- align-items: center;
- padding: 12px;
- text-align: left;
+.ogwlenmc {
+ > .local {
+ .ldhfsamy {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
+ grid-gap: 12px;
+ margin: var(--margin);
+
+ > .emoji {
+ display: flex;
+ align-items: center;
+ padding: 12px;
+ text-align: left;
- &:hover {
- color: var(--accent);
- }
+ &:hover {
+ color: var(--accent);
+ }
- > .img {
- width: 42px;
- height: 42px;
- }
+ > .img {
+ width: 42px;
+ height: 42px;
+ }
- > .body {
- padding: 0 0 0 8px;
- white-space: nowrap;
- overflow: hidden;
+ > .body {
+ padding: 0 0 0 8px;
+ white-space: nowrap;
+ overflow: hidden;
- > .name {
- text-overflow: ellipsis;
- overflow: hidden;
- }
+ > .name {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ }
- > .info {
- opacity: 0.5;
- text-overflow: ellipsis;
- overflow: hidden;
- }
+ > .info {
+ opacity: 0.5;
+ text-overflow: ellipsis;
+ overflow: hidden;
}
}
}
}
+ }
- > .remote {
- .emojis {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
- grid-gap: var(--margin);
+ > .remote {
+ .ldhfsamy {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
+ grid-gap: 12px;
+ margin: var(--margin);
- > .emoji {
- display: flex;
- align-items: center;
- padding: 12px;
- text-align: left;
+ > .emoji {
+ display: flex;
+ align-items: center;
+ padding: 12px;
+ text-align: left;
- &:hover {
- color: var(--accent);
- }
+ &:hover {
+ color: var(--accent);
+ }
- > .img {
- width: 32px;
- height: 32px;
- }
+ > .img {
+ width: 32px;
+ height: 32px;
+ }
- > .body {
- padding: 0 0 0 8px;
- white-space: nowrap;
- overflow: hidden;
+ > .body {
+ padding: 0 0 0 8px;
+ white-space: nowrap;
+ overflow: hidden;
- > .name {
- text-overflow: ellipsis;
- overflow: hidden;
- }
+ > .name {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ }
- > .info {
- opacity: 0.5;
- text-overflow: ellipsis;
- overflow: hidden;
- }
+ > .info {
+ opacity: 0.5;
+ font-size: 90%;
+ text-overflow: ellipsis;
+ overflow: hidden;
}
}
}
diff --git a/src/client/pages/instance/federation.vue b/src/client/pages/instance/federation.vue
index 2a820e5baf..96f72fed44 100644
--- a/src/client/pages/instance/federation.vue
+++ b/src/client/pages/instance/federation.vue
@@ -1,66 +1,60 @@
<template>
-<div>
- <div class="_section">
- <div class="_content">
- <MkInput v-model:value="host" :debounce="true"><span>{{ $ts.host }}</span></MkInput>
- <div class="inputs" style="display: flex;">
- <MkSelect v-model:value="state" style="margin: 0; flex: 1;">
- <template #label>{{ $ts.state }}</template>
- <option value="all">{{ $ts.all }}</option>
- <option value="federating">{{ $ts.federating }}</option>
- <option value="subscribing">{{ $ts.subscribing }}</option>
- <option value="publishing">{{ $ts.publishing }}</option>
- <option value="suspended">{{ $ts.suspended }}</option>
- <option value="blocked">{{ $ts.blocked }}</option>
- <option value="notResponding">{{ $ts.notResponding }}</option>
- </MkSelect>
- <MkSelect v-model:value="sort" style="margin: 0; flex: 1;">
- <template #label>{{ $ts.sort }}</template>
- <option value="+pubSub">{{ $ts.pubSub }} ({{ $ts.descendingOrder }})</option>
- <option value="-pubSub">{{ $ts.pubSub }} ({{ $ts.ascendingOrder }})</option>
- <option value="+notes">{{ $ts.notes }} ({{ $ts.descendingOrder }})</option>
- <option value="-notes">{{ $ts.notes }} ({{ $ts.ascendingOrder }})</option>
- <option value="+users">{{ $ts.users }} ({{ $ts.descendingOrder }})</option>
- <option value="-users">{{ $ts.users }} ({{ $ts.ascendingOrder }})</option>
- <option value="+following">{{ $ts.following }} ({{ $ts.descendingOrder }})</option>
- <option value="-following">{{ $ts.following }} ({{ $ts.ascendingOrder }})</option>
- <option value="+followers">{{ $ts.followers }} ({{ $ts.descendingOrder }})</option>
- <option value="-followers">{{ $ts.followers }} ({{ $ts.ascendingOrder }})</option>
- <option value="+caughtAt">{{ $ts.caughtAt }} ({{ $ts.descendingOrder }})</option>
- <option value="-caughtAt">{{ $ts.caughtAt }} ({{ $ts.ascendingOrder }})</option>
- <option value="+lastCommunicatedAt">{{ $ts.lastCommunicatedAt }} ({{ $ts.descendingOrder }})</option>
- <option value="-lastCommunicatedAt">{{ $ts.lastCommunicatedAt }} ({{ $ts.ascendingOrder }})</option>
- <option value="+driveUsage">{{ $ts.driveUsage }} ({{ $ts.descendingOrder }})</option>
- <option value="-driveUsage">{{ $ts.driveUsage }} ({{ $ts.ascendingOrder }})</option>
- <option value="+driveFiles">{{ $ts.driveFiles }} ({{ $ts.descendingOrder }})</option>
- <option value="-driveFiles">{{ $ts.driveFiles }} ({{ $ts.ascendingOrder }})</option>
- </MkSelect>
- </div>
+<div class="enuoauvw">
+ <div class="query">
+ <MkInput v-model:value="host" :debounce="true"><span>{{ $ts.host }}</span></MkInput>
+ <div class="inputs" style="display: flex;">
+ <MkSelect v-model:value="state" style="margin: 0; flex: 1;">
+ <template #label>{{ $ts.state }}</template>
+ <option value="all">{{ $ts.all }}</option>
+ <option value="federating">{{ $ts.federating }}</option>
+ <option value="subscribing">{{ $ts.subscribing }}</option>
+ <option value="publishing">{{ $ts.publishing }}</option>
+ <option value="suspended">{{ $ts.suspended }}</option>
+ <option value="blocked">{{ $ts.blocked }}</option>
+ <option value="notResponding">{{ $ts.notResponding }}</option>
+ </MkSelect>
+ <MkSelect v-model:value="sort" style="margin: 0; flex: 1;">
+ <template #label>{{ $ts.sort }}</template>
+ <option value="+pubSub">{{ $ts.pubSub }} ({{ $ts.descendingOrder }})</option>
+ <option value="-pubSub">{{ $ts.pubSub }} ({{ $ts.ascendingOrder }})</option>
+ <option value="+notes">{{ $ts.notes }} ({{ $ts.descendingOrder }})</option>
+ <option value="-notes">{{ $ts.notes }} ({{ $ts.ascendingOrder }})</option>
+ <option value="+users">{{ $ts.users }} ({{ $ts.descendingOrder }})</option>
+ <option value="-users">{{ $ts.users }} ({{ $ts.ascendingOrder }})</option>
+ <option value="+following">{{ $ts.following }} ({{ $ts.descendingOrder }})</option>
+ <option value="-following">{{ $ts.following }} ({{ $ts.ascendingOrder }})</option>
+ <option value="+followers">{{ $ts.followers }} ({{ $ts.descendingOrder }})</option>
+ <option value="-followers">{{ $ts.followers }} ({{ $ts.ascendingOrder }})</option>
+ <option value="+caughtAt">{{ $ts.caughtAt }} ({{ $ts.descendingOrder }})</option>
+ <option value="-caughtAt">{{ $ts.caughtAt }} ({{ $ts.ascendingOrder }})</option>
+ <option value="+lastCommunicatedAt">{{ $ts.lastCommunicatedAt }} ({{ $ts.descendingOrder }})</option>
+ <option value="-lastCommunicatedAt">{{ $ts.lastCommunicatedAt }} ({{ $ts.ascendingOrder }})</option>
+ <option value="+driveUsage">{{ $ts.driveUsage }} ({{ $ts.descendingOrder }})</option>
+ <option value="-driveUsage">{{ $ts.driveUsage }} ({{ $ts.ascendingOrder }})</option>
+ <option value="+driveFiles">{{ $ts.driveFiles }} ({{ $ts.descendingOrder }})</option>
+ <option value="-driveFiles">{{ $ts.driveFiles }} ({{ $ts.ascendingOrder }})</option>
+ </MkSelect>
</div>
</div>
- <div class="_section">
- <div class="_content">
- <MkPagination :pagination="pagination" #default="{items}" ref="instances" :key="host + state">
- <div class="ppgwaixt _panel" v-for="instance in items" :key="instance.id" @click="info(instance)">
- <div class="host"><Fa :icon="faCircle" class="indicator" :class="getStatus(instance)"/><b>{{ instance.host }}</b></div>
- <div class="status">
- <span class="sub" v-if="instance.followersCount > 0"><Fa :icon="faCaretDown" class="icon"/>Sub</span>
- <span class="sub" v-else><Fa :icon="faCaretDown" class="icon"/>-</span>
- <span class="pub" v-if="instance.followingCount > 0"><Fa :icon="faCaretUp" class="icon"/>Pub</span>
- <span class="pub" v-else><Fa :icon="faCaretUp" class="icon"/>-</span>
- <span class="lastCommunicatedAt"><Fa :icon="faExchangeAlt" class="icon"/><MkTime :time="instance.lastCommunicatedAt"/></span>
- <span class="latestStatus"><Fa :icon="faTrafficLight" class="icon"/>{{ instance.latestStatus || '-' }}</span>
- </div>
- </div>
- </MkPagination>
+
+ <MkPagination :pagination="pagination" #default="{items}" ref="instances" :key="host + state">
+ <div class="ppgwaixt _block" v-for="instance in items" :key="instance.id" @click="info(instance)">
+ <div class="host"><i class="fas fa-circle indicator" :class="getStatus(instance)"></i><b>{{ instance.host }}</b></div>
+ <div class="status">
+ <span class="sub" v-if="instance.followersCount > 0"><i class="fas fa-caret-down icon"></i>Sub</span>
+ <span class="sub" v-else><i class="fas fa-caret-down icon"></i>-</span>
+ <span class="pub" v-if="instance.followingCount > 0"><i class="fas fa-caret-up icon"></i>Pub</span>
+ <span class="pub" v-else><i class="fas fa-caret-up icon"></i>-</span>
+ <span class="lastCommunicatedAt"><i class="fas fa-exchange-alt icon"></i><MkTime :time="instance.lastCommunicatedAt"/></span>
+ <span class="latestStatus"><i class="fas fa-traffic-light icon"></i>{{ instance.latestStatus || '-' }}</span>
+ </div>
</div>
- </div>
+ </MkPagination>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faGlobe, faCircle, faExchangeAlt, faCaretDown, faCaretUp, faTrafficLight } from '@fortawesome/free-solid-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
import MkSelect from '@client/components/ui/select.vue';
@@ -77,11 +71,13 @@ export default defineComponent({
MkPagination,
},
+ emits: ['info'],
+
data() {
return {
[symbols.PAGE_INFO]: {
title: this.$ts.federation,
- icon: faGlobe
+ icon: 'fas fa-globe'
},
host: '',
state: 'federating',
@@ -103,7 +99,6 @@ export default defineComponent({
{})
})
},
- faGlobe, faCircle, faExchangeAlt, faCaretDown, faCaretUp, faTrafficLight
}
},
@@ -116,6 +111,10 @@ export default defineComponent({
}
},
+ mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
methods: {
getStatus(instance) {
if (instance.isSuspended) return 'off';
@@ -133,6 +132,12 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
+.enuoauvw {
+ > .query {
+ margin: var(--margin);
+ }
+}
+
.ppgwaixt {
cursor: pointer;
padding: 16px;
diff --git a/src/client/pages/instance/file-dialog.vue b/src/client/pages/instance/file-dialog.vue
index 85c03e3dce..74a755fa15 100644
--- a/src/client/pages/instance/file-dialog.vue
+++ b/src/client/pages/instance/file-dialog.vue
@@ -21,8 +21,8 @@
</div>
<div class="_section">
<div class="_content">
- <MkButton full @click="showUser"><Fa :icon="faExternalLinkSquareAlt"/> {{ $ts.user }}</MkButton>
- <MkButton full danger @click="del"><Fa :icon="faTrashAlt"/> {{ $ts.delete }}</MkButton>
+ <MkButton full @click="showUser"><i class="fas fa-external-link-square-alt"></i> {{ $ts.user }}</MkButton>
+ <MkButton full danger @click="del"><i class="fas fa-trash-alt"></i> {{ $ts.delete }}</MkButton>
</div>
</div>
<div class="_section" v-if="info">
@@ -36,8 +36,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faTimes, faBookmark, faKey, faSync, faMicrophoneSlash, faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
-import { faSnowflake, faTrashAlt, faBookmark as farBookmark } from '@fortawesome/free-regular-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import MkSwitch from '@client/components/ui/switch.vue';
import XModalWindow from '@client/components/ui/modal-window.vue';
@@ -67,7 +65,6 @@ export default defineComponent({
file: null,
info: null,
isSensitive: false,
- faTimes, faBookmark, farBookmark, faKey, faSync, faMicrophoneSlash, faSnowflake, faTrashAlt, faExternalLinkSquareAlt
};
},
@@ -85,9 +82,7 @@ export default defineComponent({
},
showUser() {
- os.popup(import('./user-dialog.vue'), {
- userId: this.file.userId
- }, {}, 'closed');
+ os.pageWindow(`/user-info/${this.file.userId}`);
},
async del() {
diff --git a/src/client/pages/instance/files-settings.vue b/src/client/pages/instance/files-settings.vue
new file mode 100644
index 0000000000..614c7d4dbb
--- /dev/null
+++ b/src/client/pages/instance/files-settings.vue
@@ -0,0 +1,92 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormSwitch v-model:value="cacheRemoteFiles">
+ {{ $ts.cacheRemoteFiles }}
+ <template #desc>{{ $ts.cacheRemoteFilesDescription }}</template>
+ </FormSwitch>
+
+ <FormSwitch v-model:value="proxyRemoteFiles">
+ {{ $ts.proxyRemoteFiles }}
+ <template #desc>{{ $ts.proxyRemoteFilesDescription }}</template>
+ </FormSwitch>
+
+ <FormInput v-model:value="localDriveCapacityMb" type="number">
+ <span>{{ $ts.driveCapacityPerLocalAccount }}</span>
+ <template #suffix>MB</template>
+ <template #desc>{{ $ts.inMb }}</template>
+ </FormInput>
+
+ <FormInput v-model:value="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles">
+ <span>{{ $ts.driveCapacityPerRemoteAccount }}</span>
+ <template #suffix>MB</template>
+ <template #desc>{{ $ts.inMb }}</template>
+ </FormInput>
+
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormSwitch from '@client/components/form/switch.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormSwitch,
+ FormInput,
+ FormBase,
+ FormGroup,
+ FormButton,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.files,
+ icon: 'fas fa-cloud'
+ },
+ cacheRemoteFiles: false,
+ proxyRemoteFiles: false,
+ localDriveCapacityMb: 0,
+ remoteDriveCapacityMb: 0,
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.cacheRemoteFiles = meta.cacheRemoteFiles;
+ this.proxyRemoteFiles = meta.proxyRemoteFiles;
+ this.localDriveCapacityMb = meta.driveCapacityPerLocalUserMb;
+ this.remoteDriveCapacityMb = meta.driveCapacityPerRemoteUserMb;
+ },
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ cacheRemoteFiles: this.cacheRemoteFiles,
+ proxyRemoteFiles: this.proxyRemoteFiles,
+ localDriveCapacityMb: parseInt(this.localDriveCapacityMb, 10),
+ remoteDriveCapacityMb: parseInt(this.remoteDriveCapacityMb, 10),
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/files.vue b/src/client/pages/instance/files.vue
index e7de050df8..427c5b411a 100644
--- a/src/client/pages/instance/files.vue
+++ b/src/client/pages/instance/files.vue
@@ -2,17 +2,17 @@
<div class="xrmjdkdw">
<div class="_section">
<div class="_content">
- <MkButton primary @click="clear()"><Fa :icon="faTrashAlt"/> {{ $ts.clearCachedFiles }}</MkButton>
+ <MkButton primary @click="clear()"><i class="fas fa-trash-alt"></i> {{ $ts.clearCachedFiles }}</MkButton>
</div>
</div>
<div class="_section lookup">
- <div class="_title"><Fa :icon="faSearch"/> {{ $ts.lookup }}</div>
+ <div class="_title"><i class="fas fa-search"></i> {{ $ts.lookup }}</div>
<div class="_content">
<MkInput class="target" v-model:value="q" type="text" @enter="find()">
<span>{{ $ts.fileIdOrUrl }}</span>
</MkInput>
- <MkButton @click="find()" primary><Fa :icon="faSearch"/> {{ $ts.lookup }}</MkButton>
+ <MkButton @click="find()" primary><i class="fas fa-search"></i> {{ $ts.lookup }}</MkButton>
</div>
</div>
@@ -62,8 +62,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faCloud, faSearch } from '@fortawesome/free-solid-svg-icons';
-import { faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
import MkSelect from '@client/components/ui/select.vue';
@@ -82,11 +80,13 @@ export default defineComponent({
MkDriveFileThumbnail,
},
+ emits: ['info'],
+
data() {
return {
[symbols.PAGE_INFO]: {
title: this.$ts.files,
- icon: faCloud
+ icon: 'fas fa-cloud'
},
q: null,
origin: 'local',
@@ -101,7 +101,6 @@ export default defineComponent({
hostname: (this.hostname && this.hostname !== '') ? this.hostname : null,
}),
},
- faTrashAlt, faCloud, faSearch,
}
},
@@ -117,6 +116,10 @@ export default defineComponent({
},
},
+ mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
methods: {
clear() {
os.dialog({
@@ -156,6 +159,8 @@ export default defineComponent({
<style lang="scss" scoped>
.xrmjdkdw {
+ margin: var(--margin);
+
.urempief {
margin-top: var(--margin);
diff --git a/src/client/pages/instance/index.vue b/src/client/pages/instance/index.vue
index 731acd8f00..5972a02de0 100644
--- a/src/client/pages/instance/index.vue
+++ b/src/client/pages/instance/index.vue
@@ -1,173 +1,243 @@
<template>
-<div v-if="meta" v-show="page === 'index'" class="xhexznfu _section">
- <MkFolder>
- <template #header><Fa :icon="faTachometerAlt"/> {{ $ts.overview }}</template>
-
- <div class="sboqnrfi" :style="{ gridTemplateRows: overviewHeight }">
- <MkInstanceStats :chart-limit="300" :detailed="true" class="_gap" ref="stats"/>
-
- <MkContainer :foldable="true" class="_gap">
- <template #header><Fa :icon="faInfoCircle"/>{{ $ts.instanceInfo }}</template>
-
- <div class="_content">
- <div class="_keyValue"><b>Misskey</b><span>v{{ version }}</span></div>
- </div>
- <div class="_content" v-if="serverInfo">
- <div class="_keyValue"><b>Node.js</b><span>{{ serverInfo.node }}</span></div>
- <div class="_keyValue"><b>PostgreSQL</b><span>v{{ serverInfo.psql }}</span></div>
- <div class="_keyValue"><b>Redis</b><span>v{{ serverInfo.redis }}</span></div>
- </div>
- </MkContainer>
-
- <MkContainer :foldable="true" :scrollable="true" class="_gap" style="height: 300px;">
- <template #header><Fa :icon="faDatabase"/>{{ $ts.database }}</template>
-
- <div class="_content" v-if="dbInfo">
- <table style="border-collapse: collapse; width: 100%;">
- <tr style="opacity: 0.7;">
- <th style="text-align: left; padding: 0 8px 8px 0;">Table</th>
- <th style="text-align: left; padding: 0 8px 8px 0;">Records</th>
- <th style="text-align: left; padding: 0 0 8px 0;">Size</th>
- </tr>
- <tr v-for="table in dbInfo" :key="table[0]">
- <th style="text-align: left; padding: 0 8px 0 0; word-break: break-all;">{{ table[0] }}</th>
- <td style="padding: 0 8px 0 0;">{{ number(table[1].count) }}</td>
- <td style="padding: 0; opacity: 0.7;">{{ bytes(table[1].size) }}</td>
- </tr>
- </table>
+<div class="hiyeyicy" :class="{ wide: !narrow }" ref="el">
+ <div class="nav" v-if="!narrow || page == null">
+ <FormBase>
+ <FormGroup>
+ <div class="_formItem">
+ <div class="_formPanel lxpfedzu">
+ <img :src="$instance.iconUrl || '/favicon.ico'" alt="" class="icon"/>
+ </div>
</div>
- </MkContainer>
- </div>
- </MkFolder>
-</div>
-<div v-if="page === 'logs'" class="_section">
- <MkFolder>
- <template #header><Fa :icon="faStream"/> {{ $ts.logs }}</template>
-
- <div class="_keyValue" v-for="log in modLogs">
- <b>{{ log.type }}</b><span>by {{ log.user.username }}</span><MkTime :time="log.createdAt" style="opacity: 0.7;"/>
- </div>
- </MkFolder>
-</div>
-<div v-if="page === 'metrics'">
- <XMetrics/>
+ <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 === '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>
+ </FormGroup>
+ </FormBase>
+ </div>
+ <div class="main">
+ <component :is="component" :key="page" @info="onInfo" v-bind="pageProps"/>
+ </div>
</div>
</template>
<script lang="ts">
-import { computed, defineComponent, markRaw } from 'vue';
-import { faPlay, faPause, faDatabase, faServer, faExchangeAlt, faMicrochip, faHdd, faStream, faTrashAlt, faInfoCircle, faExclamationTriangle, faTachometerAlt, faHeartbeat, faClipboardList } from '@fortawesome/free-solid-svg-icons';
-import VueJsonPretty from 'vue-json-pretty';
-import MkInstanceStats from '@client/components/instance-stats.vue';
-import MkButton from '@client/components/ui/button.vue';
-import MkSelect from '@client/components/ui/select.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkContainer from '@client/components/ui/container.vue';
-import MkFolder from '@client/components/ui/folder.vue';
-import { version, url } from '@client/config';
-import bytes from '../../filters/bytes';
-import number from '../../filters/number';
-import MkInstanceInfo from './instance.vue';
-import XMetrics from './index.metrics.vue';
-import * as os from '@client/os';
+import { computed, defineAsyncComponent, defineComponent, nextTick, onMounted, reactive, ref, watch } from 'vue';
+import { i18n } from '@client/i18n';
+import FormLink from '@client/components/form/link.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormButton from '@client/components/form/button.vue';
+import { scroll } from '@client/scripts/scroll';
import * as symbols from '@client/symbols';
+import * as os from '@client/os';
+import { lookupUser } from '@client/scripts/lookup-user';
export default defineComponent({
components: {
- MkInstanceStats,
- MkButton,
- MkSelect,
- MkInput,
- MkContainer,
- MkFolder,
- XMetrics,
- VueJsonPretty,
+ FormBase,
+ FormLink,
+ FormGroup,
+ FormButton,
},
- data() {
- return {
- [symbols.PAGE_INFO]: {
- tabs: [{
- id: 'index',
- title: null,
- tooltip: this.$ts.instance,
- icon: faServer,
- onClick: () => { this.page = 'index'; },
- selected: computed(() => this.page === 'index')
- }, {
- id: 'metrics',
- title: null,
- tooltip: this.$ts.metrics,
- icon: faHeartbeat,
- onClick: () => { this.page = 'metrics'; },
- selected: computed(() => this.page === 'metrics')
- }, {
- id: 'logs',
- title: null,
- tooltip: this.$ts.logs,
- icon: faStream,
- onClick: () => { this.page = 'logs'; },
- selected: computed(() => this.page === 'logs')
- }]
- },
- page: 'index',
- version,
- url,
- stats: null,
- serverInfo: null,
- modLogs: [],
- dbInfo: null,
- faPlay, faPause, faDatabase, faServer, faExchangeAlt, faMicrochip, faHdd, faStream, faTrashAlt, faInfoCircle, faExclamationTriangle, faTachometerAlt, faHeartbeat, faClipboardList,
+ props: {
+ initialPage: {
+ type: String,
+ required: false
}
},
- computed: {
- meta() {
- return this.$instance;
- },
- },
+ setup(props, context) {
+ const indexInfo = {
+ title: i18n.locale.instance,
+ icon: 'fas fa-cog'
+ };
+ const INFO = ref(indexInfo);
+ const page = ref(props.initialPage);
+ const narrow = ref(false);
+ const view = ref(null);
+ const el = ref(null);
+ const onInfo = (viewInfo) => {
+ INFO.value = viewInfo;
+ };
+ const pageProps = ref({});
+ const component = computed(() => {
+ if (page.value == null) return null;
+ switch (page.value) {
+ case 'overview': return defineAsyncComponent(() => import('./overview.vue'));
+ case 'users': return defineAsyncComponent(() => import('./users.vue'));
+ case 'emojis': return defineAsyncComponent(() => import('./emojis.vue'));
+ case 'federation': return defineAsyncComponent(() => import('./federation.vue'));
+ case 'queue': return defineAsyncComponent(() => import('./queue.vue'));
+ case 'files': return defineAsyncComponent(() => import('./files.vue'));
+ case 'announcements': return defineAsyncComponent(() => import('./announcements.vue'));
+ case 'database': return defineAsyncComponent(() => import('./database.vue'));
+ case 'abuses': return defineAsyncComponent(() => import('./abuses.vue'));
+ case 'settings': return defineAsyncComponent(() => import('./settings.vue'));
+ case 'files-settings': return defineAsyncComponent(() => import('./files-settings.vue'));
+ case 'email-settings': return defineAsyncComponent(() => import('./email-settings.vue'));
+ case 'object-storage': return defineAsyncComponent(() => import('./object-storage.vue'));
+ case 'security': return defineAsyncComponent(() => import('./security.vue'));
+ case 'bot-protection': return defineAsyncComponent(() => import('./bot-protection.vue'));
+ case 'service-worker': return defineAsyncComponent(() => import('./service-worker.vue'));
+ case 'relays': return defineAsyncComponent(() => import('./relays.vue'));
+ case 'integrations': return defineAsyncComponent(() => import('./integrations.vue'));
+ case 'integrations/twitter': return defineAsyncComponent(() => import('./integrations-twitter.vue'));
+ case 'integrations/github': return defineAsyncComponent(() => import('./integrations-github.vue'));
+ case 'integrations/discord': return defineAsyncComponent(() => import('./integrations-discord.vue'));
+ case 'instance-block': return defineAsyncComponent(() => import('./instance-block.vue'));
+ case 'proxy-account': return defineAsyncComponent(() => import('./proxy-account.vue'));
+ case 'other-settings': return defineAsyncComponent(() => import('./other-settings.vue'));
+ }
+ });
- mounted() {
- this.fetchJobs();
- this.fetchModLogs();
+ watch(component, () => {
+ pageProps.value = {};
- os.api('admin/server-info', {}).then(res => {
- this.serverInfo = res;
- });
+ nextTick(() => {
+ scroll(el.value, 0);
+ });
+ }, { immediate: true });
- os.api('admin/get-table-stats', {}).then(res => {
- this.dbInfo = Object.entries(res).sort((a, b) => b[1].size - a[1].size);
+ watch(() => props.initialPage, () => {
+ if (props.initialPage == null && !narrow.value) {
+ page.value = 'overview';
+ } else {
+ page.value = props.initialPage;
+ if (props.initialPage == null) {
+ INFO.value = indexInfo;
+ }
+ }
});
- },
- methods: {
- async showInstanceInfo(q) {
- let instance = q;
- if (typeof q === 'string') {
- instance = await os.api('federation/show-instance', {
- host: q
- });
+ onMounted(() => {
+ narrow.value = el.value.offsetWidth < 800;
+ if (!narrow.value) {
+ page.value = 'overview';
}
- os.popup(MkInstanceInfo, {
- instance: instance
- }, {}, 'closed');
- },
-
- fetchJobs() {
- os.api('admin/queue/deliver-delayed', {}).then(jobs => {
- this.jobs = jobs;
- });
- },
+ });
- fetchModLogs() {
- os.api('admin/show-moderation-logs', {}).then(logs => {
- this.modLogs = logs;
+ const invite = () => {
+ os.api('admin/invite').then(x => {
+ os.dialog({
+ type: 'info',
+ text: x.code
+ });
+ }).catch(e => {
+ os.dialog({
+ type: 'error',
+ text: e
+ });
});
- },
+ };
- bytes,
+ const lookup = (ev) => {
+ os.modalMenu([{
+ text: i18n.locale.user,
+ icon: 'fas fa-user',
+ action: () => {
+ lookupUser();
+ }
+ }, {
+ text: i18n.locale.note,
+ icon: 'fas fa-pencil-alt',
+ action: () => {
+ alert('TODO');
+ }
+ }, {
+ text: i18n.locale.file,
+ icon: 'fas fa-cloud',
+ action: () => {
+ alert('TODO');
+ }
+ }, {
+ text: i18n.locale.instance,
+ icon: 'fas fa-globe',
+ action: () => {
+ alert('TODO');
+ }
+ }], ev.currentTarget || ev.target);
+ };
- number,
- }
+ return {
+ [symbols.PAGE_INFO]: INFO,
+ page,
+ narrow,
+ view,
+ el,
+ onInfo,
+ pageProps,
+ component,
+ invite,
+ lookup,
+ };
+ },
});
</script>
+
+<style lang="scss" scoped>
+.hiyeyicy {
+ &.wide {
+ display: flex;
+ max-width: 1100px;
+ margin: 0 auto;
+ height: 100%;
+
+ > .nav {
+ width: 32%;
+ box-sizing: border-box;
+ border-right: solid 0.5px var(--divider);
+ overflow: auto;
+ }
+
+ > .main {
+ flex: 1;
+ min-width: 0;
+ overflow: auto;
+ --baseContentWidth: 100%;
+ }
+ }
+}
+
+.lxpfedzu {
+ padding: 16px;
+
+ > .icon {
+ display: block;
+ margin: auto;
+ height: 42px;
+ border-radius: 8px;
+ }
+}
+</style>
diff --git a/src/client/pages/instance/instance-block.vue b/src/client/pages/instance/instance-block.vue
new file mode 100644
index 0000000000..ed5740f339
--- /dev/null
+++ b/src/client/pages/instance/instance-block.vue
@@ -0,0 +1,71 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormTextarea v-model:value="blockedHosts">
+ <span>{{ $ts.blockedInstances }}</span>
+ <template #desc>{{ $ts.blockedInstancesDescription }}</template>
+ </FormTextarea>
+
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormSwitch from '@client/components/form/switch.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormTextarea from '@client/components/form/textarea.vue';
+import FormInfo from '@client/components/form/info.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormSwitch,
+ FormInput,
+ FormBase,
+ FormGroup,
+ FormButton,
+ FormTextarea,
+ FormInfo,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.instanceBlocking,
+ icon: 'fas fa-ban'
+ },
+ blockedHosts: '',
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.blockedHosts = meta.blockedHosts.join('\n');
+ },
+
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ blockedHosts: this.blockedHosts.split('\n') || [],
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/instance.vue b/src/client/pages/instance/instance.vue
index 1adb3ab9d2..f52e5d866b 100644
--- a/src/client/pages/instance/instance.vue
+++ b/src/client/pages/instance/instance.vue
@@ -106,11 +106,11 @@
<MkSwitch :value="isBlocked" class="switch" @update:value="changeBlock">{{ $ts.blockThisInstance }}</MkSwitch>
<details>
<summary>{{ $ts.deleteAllFiles }}</summary>
- <MkButton @click="deleteAllFiles()" style="margin: 0.5em 0 0.5em 0;"><Fa :icon="faTrashAlt"/> {{ $ts.deleteAllFiles }}</MkButton>
+ <MkButton @click="deleteAllFiles()" style="margin: 0.5em 0 0.5em 0;"><i class="fas fa-trash-alt"></i> {{ $ts.deleteAllFiles }}</MkButton>
</details>
<details>
<summary>{{ $ts.removeAllFollowing }}</summary>
- <MkButton @click="removeAllFollowing()" style="margin: 0.5em 0 0.5em 0;"><Fa :icon="faMinusCircle"/> {{ $ts.removeAllFollowing }}</MkButton>
+ <MkButton @click="removeAllFollowing()" style="margin: 0.5em 0 0.5em 0;"><i class="fas fa-minus-circle"></i> {{ $ts.removeAllFollowing }}</MkButton>
<MkInfo warn>{{ $t('removeAllFollowingDescription', { host: instance.host }) }}</MkInfo>
</details>
</div>
@@ -125,7 +125,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
import Chart from 'chart.js';
-import { faTimes, faCrosshairs, faCloudDownloadAlt, faCloudUploadAlt, faUsers, faPencilAlt, faFileImage, faDatabase, faTrafficLight, faLongArrowAltUp, faLongArrowAltDown, faMinusCircle, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import XModalWindow from '@client/components/ui/modal-window.vue';
import MkUsersDialog from '@client/components/users-dialog.vue';
import MkSelect from '@client/components/ui/select.vue';
@@ -174,7 +173,6 @@ export default defineComponent({
chartInstance: null,
chartSrc: 'requests',
chartSpan: 'hour',
- faTimes, faCrosshairs, faCloudDownloadAlt, faCloudUploadAlt, faUsers, faPencilAlt, faFileImage, faDatabase, faTrafficLight, faLongArrowAltUp, faLongArrowAltDown, faMinusCircle, faTrashAlt
};
},
diff --git a/src/client/pages/instance/integrations-discord.vue b/src/client/pages/instance/integrations-discord.vue
new file mode 100644
index 0000000000..c7508918f8
--- /dev/null
+++ b/src/client/pages/instance/integrations-discord.vue
@@ -0,0 +1,85 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormSwitch v-model:value="enableDiscordIntegration">
+ {{ $ts.enable }}
+ </FormSwitch>
+
+ <template v-if="enableDiscordIntegration">
+ <FormInfo>Callback URL: {{ `${url}/api/dc/cb` }}</FormInfo>
+
+ <FormInput v-model:value="discordClientId">
+ <template #prefix><i class="fas fa-key"></i></template>
+ Client ID
+ </FormInput>
+
+ <FormInput v-model:value="discordClientSecret">
+ <template #prefix><i class="fas fa-key"></i></template>
+ Client Secret
+ </FormInput>
+ </template>
+
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormSwitch from '@client/components/form/switch.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormInfo from '@client/components/form/info.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormSwitch,
+ FormInput,
+ FormBase,
+ FormInfo,
+ FormButton,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: 'Discord',
+ icon: 'fab fa-discord'
+ },
+ enableDiscordIntegration: false,
+ discordClientId: null,
+ discordClientSecret: null,
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.enableDiscordIntegration = meta.enableDiscordIntegration;
+ this.discordClientId = meta.discordClientId;
+ this.discordClientSecret = meta.discordClientSecret;
+ },
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ enableDiscordIntegration: this.enableDiscordIntegration,
+ discordClientId: this.discordClientId,
+ discordClientSecret: this.discordClientSecret,
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/integrations-github.vue b/src/client/pages/instance/integrations-github.vue
new file mode 100644
index 0000000000..16586b15b4
--- /dev/null
+++ b/src/client/pages/instance/integrations-github.vue
@@ -0,0 +1,85 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormSwitch v-model:value="enableGithubIntegration">
+ {{ $ts.enable }}
+ </FormSwitch>
+
+ <template v-if="enableGithubIntegration">
+ <FormInfo>Callback URL: {{ `${url}/api/gh/cb` }}</FormInfo>
+
+ <FormInput v-model:value="githubClientId">
+ <template #prefix><i class="fas fa-key"></i></template>
+ Client ID
+ </FormInput>
+
+ <FormInput v-model:value="githubClientSecret">
+ <template #prefix><i class="fas fa-key"></i></template>
+ Client Secret
+ </FormInput>
+ </template>
+
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormSwitch from '@client/components/form/switch.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormInfo from '@client/components/form/info.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormSwitch,
+ FormInput,
+ FormBase,
+ FormInfo,
+ FormButton,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: 'GitHub',
+ icon: 'fab fa-github'
+ },
+ enableGithubIntegration: false,
+ githubClientId: null,
+ githubClientSecret: null,
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.enableGithubIntegration = meta.enableGithubIntegration;
+ this.githubClientId = meta.githubClientId;
+ this.githubClientSecret = meta.githubClientSecret;
+ },
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ enableGithubIntegration: this.enableGithubIntegration,
+ githubClientId: this.githubClientId,
+ githubClientSecret: this.githubClientSecret,
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/integrations-twitter.vue b/src/client/pages/instance/integrations-twitter.vue
new file mode 100644
index 0000000000..b08b7f40a5
--- /dev/null
+++ b/src/client/pages/instance/integrations-twitter.vue
@@ -0,0 +1,85 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormSwitch v-model:value="enableTwitterIntegration">
+ {{ $ts.enable }}
+ </FormSwitch>
+
+ <template v-if="enableTwitterIntegration">
+ <FormInfo>Callback URL: {{ `${url}/api/tw/cb` }}</FormInfo>
+
+ <FormInput v-model:value="twitterConsumerKey">
+ <template #prefix><i class="fas fa-key"></i></template>
+ Consumer Key
+ </FormInput>
+
+ <FormInput v-model:value="twitterConsumerSecret">
+ <template #prefix><i class="fas fa-key"></i></template>
+ Consumer Secret
+ </FormInput>
+ </template>
+
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormSwitch from '@client/components/form/switch.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormInfo from '@client/components/form/info.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormSwitch,
+ FormInput,
+ FormBase,
+ FormInfo,
+ FormButton,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: 'Twitter',
+ icon: 'fab fa-twitter'
+ },
+ enableTwitterIntegration: false,
+ twitterConsumerKey: null,
+ twitterConsumerSecret: null,
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.enableTwitterIntegration = meta.enableTwitterIntegration;
+ this.twitterConsumerKey = meta.twitterConsumerKey;
+ this.twitterConsumerSecret = meta.twitterConsumerSecret;
+ },
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ enableTwitterIntegration: this.enableTwitterIntegration,
+ twitterConsumerKey: this.twitterConsumerKey,
+ twitterConsumerSecret: this.twitterConsumerSecret,
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/integrations.vue b/src/client/pages/instance/integrations.vue
new file mode 100644
index 0000000000..7debedc367
--- /dev/null
+++ b/src/client/pages/instance/integrations.vue
@@ -0,0 +1,73 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormLink to="/instance/integrations/twitter">
+ <i class="fab fa-twitter"></i> Twitter
+ <template #suffix>{{ enableTwitterIntegration ? $ts.enabled : $ts.disabled }}</template>
+ </FormLink>
+ <FormLink to="/instance/integrations/github">
+ <i class="fab fa-github"></i> GitHub
+ <template #suffix>{{ enableGithubIntegration ? $ts.enabled : $ts.disabled }}</template>
+ </FormLink>
+ <FormLink to="/instance/integrations/discord">
+ <i class="fab fa-discord"></i> Discord
+ <template #suffix>{{ enableDiscordIntegration ? $ts.enabled : $ts.disabled }}</template>
+ </FormLink>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormLink from '@client/components/form/link.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormTextarea from '@client/components/form/textarea.vue';
+import FormInfo from '@client/components/form/info.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormLink,
+ FormInput,
+ FormBase,
+ FormGroup,
+ FormButton,
+ FormTextarea,
+ FormInfo,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.integration,
+ icon: 'fas fa-share-alt'
+ },
+ enableTwitterIntegration: false,
+ enableGithubIntegration: false,
+ enableDiscordIntegration: false,
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.enableTwitterIntegration = meta.enableTwitterIntegration;
+ this.enableGithubIntegration = meta.enableGithubIntegration;
+ this.enableDiscordIntegration = meta.enableDiscordIntegration;
+ },
+ }
+});
+</script>
diff --git a/src/client/pages/instance/logs.vue b/src/client/pages/instance/logs.vue
index f27546a401..7b634259d3 100644
--- a/src/client/pages/instance/logs.vue
+++ b/src/client/pages/instance/logs.vue
@@ -24,14 +24,12 @@
</code>
</div>
- <MkButton @click="deleteAllLogs()" primary><Fa :icon="faTrashAlt"/> {{ $ts.deleteAll }}</MkButton>
+ <MkButton @click="deleteAllLogs()" primary><i class="fas fa-trash-alt"></i> {{ $ts.deleteAll }}</MkButton>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faStream } from '@fortawesome/free-solid-svg-icons';
-import { faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
import MkSelect from '@client/components/ui/select.vue';
@@ -51,12 +49,11 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.serverLogs,
- icon: faStream
+ icon: 'fas fa-stream'
},
logs: [],
logLevel: 'all',
logDomain: '',
- faTrashAlt,
}
},
diff --git a/src/client/pages/instance/index.metrics.vue b/src/client/pages/instance/metrics.vue
index 17ebf5d0d6..18cfe5eee2 100644
--- a/src/client/pages/instance/index.metrics.vue
+++ b/src/client/pages/instance/metrics.vue
@@ -1,107 +1,57 @@
<template>
-<div>
- <MkFolder>
- <template #header><Fa :icon="faHeartbeat"/> {{ $ts.metrics }}</template>
- <div class="_section" style="padding: 0 var(--margin);">
- <div class="_content">
- <MkContainer :foldable="false" class="_gap">
- <template #header><Fa :icon="faMicrochip"/>{{ $ts.cpuAndMemory }}</template>
- <!--
- <template #func>
- <button class="_button" @click="resume" :disabled="!paused"><Fa :icon="faPlay"/></button>
- <button class="_button" @click="pause" :disabled="paused"><Fa :icon="faPause"/></button>
- </template>
- -->
-
- <div class="_content" style="margin-top: -8px; margin-bottom: -12px;">
- <canvas :ref="cpumem"></canvas>
- </div>
- <div class="_content" v-if="serverInfo">
- <div class="_table">
- <div class="_row">
- <div class="_cell"><div class="_label">MEM total</div>{{ bytes(serverInfo.mem.total) }}</div>
- <div class="_cell"><div class="_label">MEM used</div>{{ bytes(memUsage) }} ({{ (memUsage / serverInfo.mem.total * 100).toFixed(0) }}%)</div>
- <div class="_cell"><div class="_label">MEM free</div>{{ bytes(serverInfo.mem.total - memUsage) }} ({{ ((serverInfo.mem.total - memUsage) / serverInfo.mem.total * 100).toFixed(0) }}%)</div>
- </div>
- </div>
- </div>
- </MkContainer>
-
- <MkContainer :foldable="false" class="_gap">
- <template #header><Fa :icon="faHdd"/> {{ $ts.disk }}</template>
- <!--
- <template #func>
- <button class="_button" @click="resume" :disabled="!paused"><Fa :icon="faPlay"/></button>
- <button class="_button" @click="pause" :disabled="paused"><Fa :icon="faPause"/></button>
- </template>
- -->
-
- <div class="_content" style="margin-top: -8px; margin-bottom: -12px;">
- <canvas :ref="disk"></canvas>
- </div>
- <div class="_content" v-if="serverInfo">
- <div class="_table">
- <div class="_row">
- <div class="_cell"><div class="_label">Disk total</div>{{ bytes(serverInfo.fs.total) }}</div>
- <div class="_cell"><div class="_label">Disk used</div>{{ bytes(serverInfo.fs.used) }} ({{ (serverInfo.fs.used / serverInfo.fs.total * 100).toFixed(0) }}%)</div>
- <div class="_cell"><div class="_label">Disk free</div>{{ bytes(serverInfo.fs.total - serverInfo.fs.used) }} ({{ ((serverInfo.fs.total - serverInfo.fs.used) / serverInfo.fs.total * 100).toFixed(0) }}%)</div>
- </div>
- </div>
- </div>
- </MkContainer>
-
- <MkContainer :foldable="false" class="_gap">
- <template #header><Fa :icon="faExchangeAlt"/> {{ $ts.network }}</template>
- <!--
- <template #func>
- <button class="_button" @click="resume" :disabled="!paused"><Fa :icon="faPlay"/></button>
- <button class="_button" @click="pause" :disabled="paused"><Fa :icon="faPause"/></button>
- </template>
- -->
-
- <div class="_content" style="margin-top: -8px; margin-bottom: -12px;">
- <canvas :ref="net"></canvas>
- </div>
- <div class="_content" v-if="serverInfo">
- <div class="_table">
- <div class="_row">
- <div class="_cell"><div class="_label">Interface</div>{{ serverInfo.net.interface }}</div>
- </div>
- </div>
- </div>
- </MkContainer>
+<div class="_formItem">
+ <div class="_formLabel"><i class="fas fa-microchip"></i> {{ $ts.cpuAndMemory }}</div>
+ <div class="_formPanel xhexznfu">
+ <div>
+ <canvas :ref="cpumem"></canvas>
+ </div>
+ <div v-if="serverInfo">
+ <div class="_table">
+ <div class="_row">
+ <div class="_cell"><div class="_label">MEM total</div>{{ bytes(serverInfo.mem.total) }}</div>
+ <div class="_cell"><div class="_label">MEM used</div>{{ bytes(memUsage) }} ({{ (memUsage / serverInfo.mem.total * 100).toFixed(0) }}%)</div>
+ <div class="_cell"><div class="_label">MEM free</div>{{ bytes(serverInfo.mem.total - memUsage) }} ({{ ((serverInfo.mem.total - memUsage) / serverInfo.mem.total * 100).toFixed(0) }}%)</div>
+ </div>
</div>
</div>
- </MkFolder>
-
- <MkFolder>
- <template #header><Fa :icon="faClipboardList"/> {{ $ts.jobQueue }}</template>
-
- <div class="vkyrmkwb" :style="{ gridTemplateRows: queueHeight }">
- <MkContainer :foldable="false" :scrollable="true" :resize-base-el="() => $el">
- <template #header><Fa :icon="faExclamationTriangle"/> {{ $ts.delayed }}</template>
-
- <div class="_content">
- <div class="_keyValue" v-for="job in jobs" :key="job[0]">
- <button class="_button" @click="showInstanceInfo(job[0])">{{ job[0] }}</button>
- <div style="text-align: right;">{{ number(job[1]) }} jobs</div>
- </div>
+ </div>
+</div>
+<div class="_formItem">
+ <div class="_formLabel"><i class="fas fa-hdd"></i> {{ $ts.disk }}</div>
+ <div class="_formPanel xhexznfu">
+ <div>
+ <canvas :ref="disk"></canvas>
+ </div>
+ <div v-if="serverInfo">
+ <div class="_table">
+ <div class="_row">
+ <div class="_cell"><div class="_label">Disk total</div>{{ bytes(serverInfo.fs.total) }}</div>
+ <div class="_cell"><div class="_label">Disk used</div>{{ bytes(serverInfo.fs.used) }} ({{ (serverInfo.fs.used / serverInfo.fs.total * 100).toFixed(0) }}%)</div>
+ <div class="_cell"><div class="_label">Disk free</div>{{ bytes(serverInfo.fs.total - serverInfo.fs.used) }} ({{ ((serverInfo.fs.total - serverInfo.fs.used) / serverInfo.fs.total * 100).toFixed(0) }}%)</div>
</div>
- </MkContainer>
- <XQueue :connection="queueConnection" domain="inbox" ref="queue" class="queue">
- <template #title><Fa :icon="faExchangeAlt"/> In</template>
- </XQueue>
- <XQueue :connection="queueConnection" domain="deliver" class="queue">
- <template #title><Fa :icon="faExchangeAlt"/> Out</template>
- </XQueue>
+ </div>
+ </div>
+ </div>
+</div>
+<div class="_formItem">
+ <div class="_formLabel"><i class="fas fa-exchange-alt"></i> {{ $ts.network }}</div>
+ <div class="_formPanel xhexznfu">
+ <div>
+ <canvas :ref="net"></canvas>
+ </div>
+ <div v-if="serverInfo">
+ <div class="_table">
+ <div class="_row">
+ <div class="_cell"><div class="_label">Interface</div>{{ serverInfo.net.interface }}</div>
+ </div>
+ </div>
</div>
- </MkFolder>
+ </div>
</div>
</template>
<script lang="ts">
import { defineComponent, markRaw } from 'vue';
-import { faPlay, faPause, faDatabase, faServer, faExchangeAlt, faMicrochip, faHdd, faStream, faTrashAlt, faInfoCircle, faExclamationTriangle, faTachometerAlt, faHeartbeat, faClipboardList } from '@fortawesome/free-solid-svg-icons';
import Chart from 'chart.js';
import MkButton from '@client/components/ui/button.vue';
import MkSelect from '@client/components/ui/select.vue';
@@ -153,7 +103,6 @@ export default defineComponent({
overviewHeight: '1fr',
queueHeight: '1fr',
paused: false,
- faPlay, faPause, faDatabase, faServer, faExchangeAlt, faMicrochip, faHdd, faStream, faTrashAlt, faInfoCircle, faExclamationTriangle, faTachometerAlt, faHeartbeat, faClipboardList,
}
},
@@ -190,9 +139,11 @@ export default defineComponent({
},
beforeUnmount() {
- this.connection.off('stats', this.onStats);
- this.connection.off('statsLog', this.onStatsLog);
- this.connection.dispose();
+ if (this.connection) {
+ this.connection.off('stats', this.onStats);
+ this.connection.off('statsLog', this.onStatsLog);
+ this.connection.dispose();
+ }
this.queueConnection.dispose();
},
@@ -234,9 +185,9 @@ export default defineComponent({
aspectRatio: 3,
layout: {
padding: {
- left: 0,
- right: 0,
- top: 8,
+ left: 16,
+ right: 16,
+ top: 16,
bottom: 0
}
},
@@ -306,9 +257,9 @@ export default defineComponent({
aspectRatio: 3,
layout: {
padding: {
- left: 0,
- right: 0,
- top: 8,
+ left: 16,
+ right: 16,
+ top: 16,
bottom: 0
}
},
@@ -377,9 +328,9 @@ export default defineComponent({
aspectRatio: 3,
layout: {
padding: {
- left: 0,
- right: 0,
- top: 8,
+ left: 16,
+ right: 16,
+ top: 16,
bottom: 0
}
},
@@ -496,81 +447,9 @@ export default defineComponent({
<style lang="scss" scoped>
.xhexznfu {
- &.min-width_1000px {
- .sboqnrfi {
- display: grid;
- grid-template-columns: 3.2fr 1fr;
- grid-template-rows: 1fr;
- gap: 16px 16px;
-
- > .stats {
- height: min-content;
- }
-
- > .column {
- display: flex;
- flex-direction: column;
-
- > .info {
- flex-shrink: 0;
- flex-grow: 0;
- }
-
- > .db {
- flex: 1;
- flex-grow: 0;
- height: 100%;
- }
-
- > .fed {
- flex: 1;
- flex-grow: 0;
- height: 100%;
- }
-
- > *:not(:last-child) {
- margin-bottom: var(--margin);
- }
- }
- }
-
- .segusily {
- display: grid;
- grid-template-columns: 1fr 1fr 1fr;
- grid-template-rows: 1fr;
- gap: 16px 16px;
- padding: 0 16px;
- }
-
- .vkyrmkwb {
- display: grid;
- grid-template-columns: 0.5fr 1fr 1fr;
- grid-template-rows: 1fr;
- gap: 16px 16px;
- margin-bottom: var(--margin);
-
- > .queue {
- height: min-content;
- }
-
- > * {
- margin-bottom: 0;
- }
- }
-
- .uwuemslx {
- display: grid;
- grid-template-columns: 2fr 3fr;
- grid-template-rows: 1fr;
- gap: 16px 16px;
- height: 400px;
- }
- }
-
- .vkyrmkwb {
- > * {
- margin-bottom: var(--margin);
- }
+ > div:nth-child(2) {
+ padding: 16px;
+ border-top: solid 0.5px var(--divider);
}
}
</style>
diff --git a/src/client/pages/instance/object-storage.vue b/src/client/pages/instance/object-storage.vue
new file mode 100644
index 0000000000..814aeb6e48
--- /dev/null
+++ b/src/client/pages/instance/object-storage.vue
@@ -0,0 +1,154 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormSwitch v-model:value="useObjectStorage">{{ $ts.useObjectStorage }}</FormSwitch>
+
+ <template v-if="useObjectStorage">
+ <FormInput v-model:value="objectStorageBaseUrl">
+ <span>{{ $ts.objectStorageBaseUrl }}</span>
+ <template #desc>{{ $ts.objectStorageBaseUrlDesc }}</template>
+ </FormInput>
+
+ <FormInput v-model:value="objectStorageBucket">
+ <span>{{ $ts.objectStorageBucket }}</span>
+ <template #desc>{{ $ts.objectStorageBucketDesc }}</template>
+ </FormInput>
+
+ <FormInput v-model:value="objectStoragePrefix">
+ <span>{{ $ts.objectStoragePrefix }}</span>
+ <template #desc>{{ $ts.objectStoragePrefixDesc }}</template>
+ </FormInput>
+
+ <FormInput v-model:value="objectStorageEndpoint">
+ <span>{{ $ts.objectStorageEndpoint }}</span>
+ <template #desc>{{ $ts.objectStorageEndpointDesc }}</template>
+ </FormInput>
+
+ <FormInput v-model:value="objectStorageRegion">
+ <span>{{ $ts.objectStorageRegion }}</span>
+ <template #desc>{{ $ts.objectStorageRegionDesc }}</template>
+ </FormInput>
+
+ <FormInput v-model:value="objectStorageAccessKey">
+ <template #prefix><i class="fas fa-key"></i></template>
+ <span>Access key</span>
+ </FormInput>
+
+ <FormInput v-model:value="objectStorageSecretKey">
+ <template #prefix><i class="fas fa-key"></i></template>
+ <span>Secret key</span>
+ </FormInput>
+
+ <FormSwitch v-model:value="objectStorageUseSSL">
+ {{ $ts.objectStorageUseSSL }}
+ <template #desc>{{ $ts.objectStorageUseSSLDesc }}</template>
+ </FormSwitch>
+
+ <FormSwitch v-model:value="objectStorageUseProxy">
+ {{ $ts.objectStorageUseProxy }}
+ <template #desc>{{ $ts.objectStorageUseProxyDesc }}</template>
+ </FormSwitch>
+
+ <FormSwitch v-model:value="objectStorageSetPublicRead">
+ {{ $ts.objectStorageSetPublicRead }}
+ </FormSwitch>
+
+ <FormSwitch v-model:value="objectStorageS3ForcePathStyle">
+ s3ForcePathStyle
+ </FormSwitch>
+ </template>
+
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormSwitch from '@client/components/form/switch.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormSwitch,
+ FormInput,
+ FormBase,
+ FormGroup,
+ FormButton,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.objectStorage,
+ icon: 'fas fa-cloud'
+ },
+ useObjectStorage: false,
+ objectStorageBaseUrl: null,
+ objectStorageBucket: null,
+ objectStoragePrefix: null,
+ objectStorageEndpoint: null,
+ objectStorageRegion: null,
+ objectStoragePort: null,
+ objectStorageAccessKey: null,
+ objectStorageSecretKey: null,
+ objectStorageUseSSL: false,
+ objectStorageUseProxy: false,
+ objectStorageSetPublicRead: false,
+ objectStorageS3ForcePathStyle: true,
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.useObjectStorage = meta.useObjectStorage;
+ this.objectStorageBaseUrl = meta.objectStorageBaseUrl;
+ this.objectStorageBucket = meta.objectStorageBucket;
+ this.objectStoragePrefix = meta.objectStoragePrefix;
+ this.objectStorageEndpoint = meta.objectStorageEndpoint;
+ this.objectStorageRegion = meta.objectStorageRegion;
+ this.objectStoragePort = meta.objectStoragePort;
+ this.objectStorageAccessKey = meta.objectStorageAccessKey;
+ this.objectStorageSecretKey = meta.objectStorageSecretKey;
+ this.objectStorageUseSSL = meta.objectStorageUseSSL;
+ this.objectStorageUseProxy = meta.objectStorageUseProxy;
+ this.objectStorageSetPublicRead = meta.objectStorageSetPublicRead;
+ this.objectStorageS3ForcePathStyle = meta.objectStorageS3ForcePathStyle;
+ },
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ useObjectStorage: this.useObjectStorage,
+ objectStorageBaseUrl: this.objectStorageBaseUrl ? this.objectStorageBaseUrl : null,
+ objectStorageBucket: this.objectStorageBucket ? this.objectStorageBucket : null,
+ objectStoragePrefix: this.objectStoragePrefix ? this.objectStoragePrefix : null,
+ objectStorageEndpoint: this.objectStorageEndpoint ? this.objectStorageEndpoint : null,
+ objectStorageRegion: this.objectStorageRegion ? this.objectStorageRegion : null,
+ objectStoragePort: this.objectStoragePort ? this.objectStoragePort : null,
+ objectStorageAccessKey: this.objectStorageAccessKey ? this.objectStorageAccessKey : null,
+ objectStorageSecretKey: this.objectStorageSecretKey ? this.objectStorageSecretKey : null,
+ objectStorageUseSSL: this.objectStorageUseSSL,
+ objectStorageUseProxy: this.objectStorageUseProxy,
+ objectStorageSetPublicRead: this.objectStorageSetPublicRead,
+ objectStorageS3ForcePathStyle: this.objectStorageS3ForcePathStyle,
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/other-settings.vue b/src/client/pages/instance/other-settings.vue
new file mode 100644
index 0000000000..b3954149a8
--- /dev/null
+++ b/src/client/pages/instance/other-settings.vue
@@ -0,0 +1,68 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormGroup>
+ <FormInput v-model:value="summalyProxy">
+ <template #prefix><i class="fas fa-link"></i></template>
+ Summaly Proxy URL
+ </FormInput>
+ </FormGroup>
+
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormSwitch from '@client/components/form/switch.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormSwitch,
+ FormInput,
+ FormBase,
+ FormGroup,
+ FormButton,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.other,
+ icon: 'fas fa-cogs'
+ },
+ summalyProxy: '',
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.summalyProxy = meta.summalyProxy;
+ },
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ summalyProxy: this.summalyProxy,
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/overview.vue b/src/client/pages/instance/overview.vue
new file mode 100644
index 0000000000..dca2529e1b
--- /dev/null
+++ b/src/client/pages/instance/overview.vue
@@ -0,0 +1,135 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormInfo v-if="noMaintainerInformation" warn>{{ $ts.noMaintainerInformationWarning }} <MkA to="/instance/settings" class="_link">{{ $ts.configure }}</MkA></FormInfo>
+ <FormInfo v-if="noBotProtection" warn>{{ $ts.noBotProtectionWarning }} <MkA to="/instance/bot-protection" class="_link">{{ $ts.configure }}</MkA></FormInfo>
+
+ <FormSuspense :p="fetchStats" v-slot="{ result: stats }">
+ <FormGroup>
+ <FormKeyValueView>
+ <template #key>Users</template>
+ <template #value>{{ number(stats.originalUsersCount) }}</template>
+ </FormKeyValueView>
+ <FormKeyValueView>
+ <template #key>Notes</template>
+ <template #value>{{ number(stats.originalNotesCount) }}</template>
+ </FormKeyValueView>
+ </FormGroup>
+ </FormSuspense>
+
+ <div class="_formItem">
+ <div class="_formPanel">
+ <MkInstanceStats :chart-limit="300" :detailed="true"/>
+ </div>
+ </div>
+
+ <XMetrics/>
+
+ <FormSuspense :p="fetchServerInfo" v-slot="{ result: serverInfo }">
+ <FormGroup>
+ <FormKeyValueView>
+ <template #key>Node.js</template>
+ <template #value>{{ serverInfo.node }}</template>
+ </FormKeyValueView>
+ <FormKeyValueView>
+ <template #key>PostgreSQL</template>
+ <template #value>{{ serverInfo.psql }}</template>
+ </FormKeyValueView>
+ <FormKeyValueView>
+ <template #key>Redis</template>
+ <template #value>{{ serverInfo.redis }}</template>
+ </FormKeyValueView>
+ </FormGroup>
+ </FormSuspense>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { computed, defineComponent, markRaw } from 'vue';
+import FormKeyValueView from '@client/components/form/key-value-view.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormTextarea from '@client/components/form/textarea.vue';
+import FormInfo from '@client/components/form/info.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import MkInstanceStats from '@client/components/instance-stats.vue';
+import MkButton from '@client/components/ui/button.vue';
+import MkSelect from '@client/components/ui/select.vue';
+import MkInput from '@client/components/ui/input.vue';
+import MkContainer from '@client/components/ui/container.vue';
+import MkFolder from '@client/components/ui/folder.vue';
+import { version, url } from '@client/config';
+import bytes from '../../filters/bytes';
+import number from '../../filters/number';
+import MkInstanceInfo from './instance.vue';
+import XMetrics from './metrics.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+
+export default defineComponent({
+ components: {
+ FormBase,
+ FormSuspense,
+ FormGroup,
+ FormInfo,
+ FormKeyValueView,
+ MkInstanceStats,
+ XMetrics,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.overview,
+ icon: 'fas fa-tachometer-alt'
+ },
+ page: 'index',
+ version,
+ url,
+ stats: null,
+ fetchStats: () => os.api('stats', {}),
+ fetchServerInfo: () => os.api('admin/server-info', {}),
+ fetchJobs: () => os.api('admin/queue/deliver-delayed', {}),
+ fetchModLogs: () => os.api('admin/show-moderation-logs', {}),
+ noMaintainerInformation: false,
+ noBotProtection: false,
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ this.meta = await os.api('meta', { detail: true });
+
+ const isEmpty = (x: any) => x == null || x == '';
+
+ this.noMaintainerInformation = isEmpty(this.meta.maintainerName) || isEmpty(this.meta.maintainerEmail);
+ this.noBotProtection = !this.meta.enableHcaptcha && !this.meta.enableRecaptcha;
+ },
+
+ async showInstanceInfo(q) {
+ let instance = q;
+ if (typeof q === 'string') {
+ instance = await os.api('federation/show-instance', {
+ host: q
+ });
+ }
+ os.popup(MkInstanceInfo, {
+ instance: instance
+ }, {}, 'closed');
+ },
+
+ bytes,
+
+ number,
+ }
+});
+</script>
diff --git a/src/client/pages/instance/proxy-account.vue b/src/client/pages/instance/proxy-account.vue
new file mode 100644
index 0000000000..3e2df8dcb4
--- /dev/null
+++ b/src/client/pages/instance/proxy-account.vue
@@ -0,0 +1,86 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormGroup>
+ <FormKeyValueView>
+ <template #key>{{ $ts.proxyAccount }}</template>
+ <template #value>{{ proxyAccount ? `@${proxyAccount.username}` : $ts.none }}</template>
+ </FormKeyValueView>
+ <template #caption>{{ $ts.proxyAccountDescription }}</template>
+ </FormGroup>
+
+ <FormButton @click="chooseProxyAccount" primary>{{ $ts.selectAccount }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormKeyValueView from '@client/components/form/key-value-view.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormTextarea from '@client/components/form/textarea.vue';
+import FormInfo from '@client/components/form/info.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormKeyValueView,
+ FormInput,
+ FormBase,
+ FormGroup,
+ FormButton,
+ FormTextarea,
+ FormInfo,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.proxyAccount,
+ icon: 'fas fa-ghost'
+ },
+ proxyAccount: null,
+ proxyAccountId: null,
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.proxyAccountId = meta.proxyAccountId;
+ if (this.proxyAccountId) {
+ this.proxyAccount = await os.api('users/show', { userId: this.proxyAccountId });
+ }
+ },
+
+ chooseProxyAccount() {
+ os.selectUser().then(user => {
+ this.proxyAccount = user;
+ this.proxyAccountId = user.id;
+ this.save();
+ });
+ },
+
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ proxyAccountId: this.proxyAccountId,
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/queue.chart.vue b/src/client/pages/instance/queue.chart.vue
index 0eb70debfb..446c979209 100644
--- a/src/client/pages/instance/queue.chart.vue
+++ b/src/client/pages/instance/queue.chart.vue
@@ -1,27 +1,29 @@
<template>
-<section class="_section">
- <div class="_title"><slot name="title"></slot></div>
- <div class="_content _table">
- <div class="_row">
- <div class="_cell"><div class="_label">Process</div>{{ number(activeSincePrevTick) }}</div>
- <div class="_cell"><div class="_label">Active</div>{{ number(active) }}</div>
- <div class="_cell"><div class="_label">Waiting</div>{{ number(waiting) }}</div>
- <div class="_cell"><div class="_label">Delayed</div>{{ number(delayed) }}</div>
+<div class="_formItem">
+ <div class="_formLabel"><slot name="title"></slot></div>
+ <div class="_formPanel pumxzjhg">
+ <div class="_table status">
+ <div class="_row">
+ <div class="_cell"><div class="_label">Process</div>{{ number(activeSincePrevTick) }}</div>
+ <div class="_cell"><div class="_label">Active</div>{{ number(active) }}</div>
+ <div class="_cell"><div class="_label">Waiting</div>{{ number(waiting) }}</div>
+ <div class="_cell"><div class="_label">Delayed</div>{{ number(delayed) }}</div>
+ </div>
</div>
- </div>
- <div class="_content" style="margin-bottom: -8px;">
- <canvas ref="chart"></canvas>
- </div>
- <div class="_content" style="max-height: 180px; overflow: auto;">
- <div v-if="jobs.length > 0">
- <div v-for="job in jobs" :key="job[0]">
- <span>{{ job[0] }}</span>
- <span style="margin-left: 8px; opacity: 0.7;">({{ number(job[1]) }} jobs)</span>
+ <div class="">
+ <canvas ref="chart"></canvas>
+ </div>
+ <div class="jobs">
+ <div v-if="jobs.length > 0">
+ <div v-for="job in jobs" :key="job[0]">
+ <span>{{ job[0] }}</span>
+ <span style="margin-left: 8px; opacity: 0.7;">({{ number(job[1]) }} jobs)</span>
+ </div>
</div>
+ <span v-else style="opacity: 0.5;">{{ $ts.noJobs }}</span>
</div>
- <span v-else style="opacity: 0.5;">{{ $ts.noJobs }}</span>
</div>
-</section>
+</div>
</template>
<script lang="ts">
@@ -110,10 +112,10 @@ export default defineComponent({
aspectRatio: 3,
layout: {
padding: {
- left: 0,
- right: 0,
- top: 8,
- bottom: 0
+ left: 16,
+ right: 16,
+ top: 16,
+ bottom: 12
}
},
legend: {
@@ -198,3 +200,19 @@ export default defineComponent({
}
});
</script>
+
+<style lang="scss" scoped>
+.pumxzjhg {
+ > .status {
+ padding: 16px;
+ border-bottom: solid 0.5px var(--divider);
+ }
+
+ > .jobs {
+ padding: 16px;
+ border-top: solid 0.5px var(--divider);
+ max-height: 180px;
+ overflow: auto;
+ }
+}
+</style>
diff --git a/src/client/pages/instance/queue.vue b/src/client/pages/instance/queue.vue
index 249babcf41..2dccf48d31 100644
--- a/src/client/pages/instance/queue.vue
+++ b/src/client/pages/instance/queue.vue
@@ -1,46 +1,47 @@
<template>
-<div>
+<FormBase>
<XQueue :connection="connection" domain="inbox">
- <template #title><Fa :icon="faExchangeAlt"/> In</template>
+ <template #title>In</template>
</XQueue>
<XQueue :connection="connection" domain="deliver">
- <template #title><Fa :icon="faExchangeAlt"/> Out</template>
+ <template #title>Out</template>
</XQueue>
- <section class="_section">
- <div class="_content">
- <MkButton @click="clear()"><Fa :icon="faTrashAlt"/> {{ $ts.clearQueue }}</MkButton>
- </div>
- </section>
-</div>
+ <FormButton @click="clear()" danger><i class="fas fa-trash-alt"></i> {{ $ts.clearQueue }}</FormButton>
+</FormBase>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faExchangeAlt } from '@fortawesome/free-solid-svg-icons';
-import { faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import XQueue from './queue.chart.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormButton from '@client/components/form/button.vue';
import * as os from '@client/os';
import * as symbols from '@client/symbols';
export default defineComponent({
components: {
+ FormBase,
+ FormButton,
MkButton,
XQueue,
},
+ emits: ['info'],
+
data() {
return {
[symbols.PAGE_INFO]: {
title: this.$ts.jobQueue,
- icon: faExchangeAlt,
+ icon: 'fas fa-clipboard-list',
},
connection: os.stream.useSharedConnection('queueStats'),
- faExchangeAlt, faTrashAlt
}
},
mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+
this.$nextTick(() => {
this.connection.send('requestLog', {
id: Math.random().toString().substr(2, 8),
diff --git a/src/client/pages/instance/relays.vue b/src/client/pages/instance/relays.vue
index d97a07cbb2..a3e4e7d1da 100644
--- a/src/client/pages/instance/relays.vue
+++ b/src/client/pages/instance/relays.vue
@@ -1,50 +1,44 @@
<template>
-<div class="relaycxt">
- <section class="_section add">
- <div class="_title"><Fa :icon="faPlus"/> {{ $ts.addRelay }}</div>
- <div class="_content">
- <MkInput v-model:value="inbox">
- <span>{{ $ts.inboxUrl }}</span>
- </MkInput>
- <MkButton @click="add(inbox)" primary><Fa :icon="faPlus"/> {{ $ts.add }}</MkButton>
- </div>
- </section>
+<FormBase class="relaycxt">
+ <FormButton @click="addRelay" primary><i class="fas fa-plus"></i> {{ $ts.addRelay }}</FormButton>
- <section class="_section relays">
- <div class="_title"><Fa :icon="faProjectDiagram"/> {{ $ts.addedRelays }}</div>
- <div class="_content relay" v-for="relay in relays" :key="relay.inbox">
+ <div class="_formItem" v-for="relay in relays" :key="relay.inbox">
+ <div class="_formPanel" style="padding: 16px;">
<div>{{ relay.inbox }}</div>
<div>{{ $t(`_relayStatus.${relay.status}`) }}</div>
- <MkButton class="button" inline @click="remove(relay.inbox)"><Fa :icon="faTrashAlt"/> {{ $ts.remove }}</MkButton>
+ <MkButton class="button" inline danger @click="remove(relay.inbox)"><i class="fas fa-trash-alt"></i> {{ $ts.remove }}</MkButton>
</div>
- </section>
-</div>
+ </div>
+</FormBase>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPlus, faProjectDiagram } from '@fortawesome/free-solid-svg-icons';
-import { faSave, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormButton from '@client/components/form/button.vue';
import * as os from '@client/os';
import * as symbols from '@client/symbols';
export default defineComponent({
components: {
+ FormBase,
+ FormButton,
MkButton,
MkInput,
},
+ emits: ['info'],
+
data() {
return {
[symbols.PAGE_INFO]: {
title: this.$ts.relays,
- icon: faProjectDiagram,
+ icon: 'fas fa-globe',
},
relays: [],
inbox: '',
- faPlus, faProjectDiagram, faSave, faTrashAlt
}
},
@@ -52,8 +46,19 @@ export default defineComponent({
this.refresh();
},
+ mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
methods: {
- add(inbox: string) {
+ async addRelay() {
+ const { canceled, result: inbox } = await os.dialog({
+ title: this.$ts.addRelay,
+ input: {
+ placeholder: this.$ts.inboxUrl
+ }
+ });
+ if (canceled) return;
os.api('admin/relays/add', {
inbox
}).then((relay: any) => {
@@ -89,9 +94,5 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
-._content.relay {
- div {
- margin: 0.5em 0;
- }
-}
+
</style>
diff --git a/src/client/pages/instance/security.vue b/src/client/pages/instance/security.vue
new file mode 100644
index 0000000000..e3397a113b
--- /dev/null
+++ b/src/client/pages/instance/security.vue
@@ -0,0 +1,77 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormLink to="/instance/bot-protection">
+ <i class="fas fa-shield-alt"></i> {{ $ts.botProtection }}
+ <template #suffix v-if="enableHcaptcha">hCaptcha</template>
+ <template #suffix v-else-if="enableRecaptcha">reCAPTCHA</template>
+ <template #suffix v-else>{{ $ts.none }} ({{ $ts.notRecommended }})</template>
+ </FormLink>
+
+ <FormSwitch v-model:value="enableRegistration">{{ $ts.enableRegistration }}</FormSwitch>
+
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineAsyncComponent, defineComponent } from 'vue';
+import FormLink from '@client/components/form/link.vue';
+import FormSwitch from '@client/components/form/switch.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormInfo from '@client/components/form/info.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormLink,
+ FormSwitch,
+ FormBase,
+ FormGroup,
+ FormButton,
+ FormInfo,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.security,
+ icon: 'fas fa-lock'
+ },
+ enableHcaptcha: false,
+ enableRecaptcha: false,
+ enableRegistration: false,
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.enableHcaptcha = meta.enableHcaptcha;
+ this.enableRecaptcha = meta.enableRecaptcha;
+ this.enableRegistration = !meta.disableRegistration;
+ },
+
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ disableRegistration: !this.enableRegistration,
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/service-worker.vue b/src/client/pages/instance/service-worker.vue
new file mode 100644
index 0000000000..a52932bb75
--- /dev/null
+++ b/src/client/pages/instance/service-worker.vue
@@ -0,0 +1,84 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormSwitch v-model:value="enableServiceWorker">
+ {{ $ts.enableServiceworker }}
+ <template #desc>{{ $ts.serviceworkerInfo }}</template>
+ </FormSwitch>
+
+ <template v-if="enableServiceWorker">
+ <FormInput v-model:value="swPublicKey">
+ <template #prefix><i class="fas fa-key"></i></template>
+ Public key
+ </FormInput>
+
+ <FormInput v-model:value="swPrivateKey">
+ <template #prefix><i class="fas fa-key"></i></template>
+ Private key
+ </FormInput>
+ </template>
+
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormSwitch from '@client/components/form/switch.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
+
+export default defineComponent({
+ components: {
+ FormSwitch,
+ FormInput,
+ FormBase,
+ FormGroup,
+ FormButton,
+ FormSuspense,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: 'ServiceWorker',
+ icon: 'fas fa-bolt'
+ },
+ enableServiceWorker: false,
+ swPublicKey: null,
+ swPrivateKey: null,
+ }
+ },
+
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.enableServiceWorker = meta.enableServiceWorker;
+ this.swPublicKey = meta.swPublickey;
+ this.swPrivateKey = meta.swPrivateKey;
+ },
+ save() {
+ os.apiWithDialog('admin/update-meta', {
+ enableServiceWorker: this.enableServiceWorker,
+ swPublicKey: this.swPublicKey,
+ swPrivateKey: this.swPrivateKey,
+ }).then(() => {
+ fetchInstance();
+ });
+ }
+ }
+});
+</script>
diff --git a/src/client/pages/instance/settings.vue b/src/client/pages/instance/settings.vue
index 038ecfd5ac..66f01c42c7 100644
--- a/src/client/pages/instance/settings.vue
+++ b/src/client/pages/instance/settings.vue
@@ -1,585 +1,132 @@
<template>
-<div v-if="meta" class="_section">
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faInfoCircle"/> {{ $ts.basicInfo }}</div>
- <div class="_content">
- <MkInput v-model:value="name">{{ $ts.instanceName }}</MkInput>
- <MkTextarea v-model:value="description">{{ $ts.instanceDescription }}</MkTextarea>
- <MkInput v-model:value="iconUrl"><template #icon><Fa :icon="faLink"/></template>{{ $ts.iconUrl }}</MkInput>
- <MkInput v-model:value="bannerUrl"><template #icon><Fa :icon="faLink"/></template>{{ $ts.bannerUrl }}</MkInput>
- <MkInput v-model:value="backgroundImageUrl"><template #icon><Fa :icon="faLink"/></template>{{ $ts.backgroundImageUrl }}</MkInput>
- <MkInput v-model:value="logoImageUrl"><template #icon><Fa :icon="faLink"/></template>{{ $ts.logoImageUrl }}</MkInput>
- <MkInput v-model:value="tosUrl"><template #icon><Fa :icon="faLink"/></template>{{ $ts.tosUrl }}</MkInput>
- <MkInput v-model:value="maintainerName">{{ $ts.maintainerName }}</MkInput>
- <MkInput v-model:value="maintainerEmail" type="email"><template #icon><Fa :icon="faEnvelope"/></template>{{ $ts.maintainerEmail }}</MkInput>
- </div>
- <div class="_footer">
- <MkButton primary @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- </div>
- </section>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormInput v-model:value="name">
+ <span>{{ $ts.instanceName }}</span>
+ </FormInput>
- <MkInput v-model:value="pinnedClipId">{{ $ts.pinnedClipId }}</MkInput>
+ <FormTextarea v-model:value="description">
+ <span>{{ $ts.instanceDescription }}</span>
+ </FormTextarea>
- <section class="_card _gap">
- <div class="_content">
- <MkInput v-model:value="maxNoteTextLength" type="number" :save="() => save()"><template #icon><Fa :icon="faPencilAlt"/></template>{{ $ts.maxNoteTextLength }}</MkInput>
- </div>
- <div class="_content">
- <MkSwitch v-model:value="enableLocalTimeline" @update:value="save()">{{ $ts.enableLocalTimeline }}</MkSwitch>
- <MkSwitch v-model:value="enableGlobalTimeline" @update:value="save()">{{ $ts.enableGlobalTimeline }}</MkSwitch>
- <MkInfo>{{ $ts.disablingTimelinesInfo }}</MkInfo>
- </div>
- <div class="_content">
- <MkSwitch v-model:value="useStarForReactionFallback" @update:value="save()">{{ $ts.useStarForReactionFallback }}</MkSwitch>
- </div>
- </section>
+ <FormInput v-model:value="iconUrl">
+ <template #prefix><i class="fas fa-link"></i></template>
+ <span>{{ $ts.iconUrl }}</span>
+ </FormInput>
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faUser"/> {{ $ts.registration }}</div>
- <div class="_content">
- <MkSwitch v-model:value="enableRegistration" @update:value="save()">{{ $ts.enableRegistration }}</MkSwitch>
- <MkButton v-if="!enableRegistration" @click="invite">{{ $ts.invite }}</MkButton>
- </div>
- </section>
+ <FormInput v-model:value="bannerUrl">
+ <template #prefix><i class="fas fa-link"></i></template>
+ <span>{{ $ts.bannerUrl }}</span>
+ </FormInput>
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faShieldAlt"/> {{ $ts.hcaptcha }}</div>
- <div class="_content">
- <MkSwitch v-model:value="enableHcaptcha">{{ $ts.enableHcaptcha }}</MkSwitch>
- <template v-if="enableHcaptcha">
- <MkInput v-model:value="hcaptchaSiteKey" :disabled="!enableHcaptcha"><template #icon><Fa :icon="faKey"/></template>{{ $ts.hcaptchaSiteKey }}</MkInput>
- <MkInput v-model:value="hcaptchaSecretKey" :disabled="!enableHcaptcha"><template #icon><Fa :icon="faKey"/></template>{{ $ts.hcaptchaSecretKey }}</MkInput>
- </template>
- </div>
- <div class="_content" v-if="enableHcaptcha">
- <header>{{ $ts.preview }}</header>
- <captcha v-if="enableHcaptcha" provider="hcaptcha" :sitekey="hcaptchaSiteKey || '10000000-ffff-ffff-ffff-000000000001'"/>
- </div>
- <div class="_footer">
- <MkButton primary @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- </div>
- </section>
+ <FormInput v-model:value="tosUrl">
+ <template #prefix><i class="fas fa-link"></i></template>
+ <span>{{ $ts.tosUrl }}</span>
+ </FormInput>
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faShieldAlt"/> {{ $ts.recaptcha }}</div>
- <div class="_content">
- <MkSwitch v-model:value="enableRecaptcha" ref="enableRecaptcha">{{ $ts.enableRecaptcha }}</MkSwitch>
- <template v-if="enableRecaptcha">
- <MkInput v-model:value="recaptchaSiteKey" :disabled="!enableRecaptcha"><template #icon><Fa :icon="faKey"/></template>{{ $ts.recaptchaSiteKey }}</MkInput>
- <MkInput v-model:value="recaptchaSecretKey" :disabled="!enableRecaptcha"><template #icon><Fa :icon="faKey"/></template>{{ $ts.recaptchaSecretKey }}</MkInput>
- </template>
- </div>
- <div class="_content" v-if="enableRecaptcha && recaptchaSiteKey">
- <header>{{ $ts.preview }}</header>
- <captcha v-if="enableRecaptcha" provider="grecaptcha" :sitekey="recaptchaSiteKey"/>
- </div>
- <div class="_footer">
- <MkButton primary @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- </div>
- </section>
+ <FormInput v-model:value="maintainerName">
+ <span>{{ $ts.maintainerName }}</span>
+ </FormInput>
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faEnvelope" /> {{ $ts.emailConfig }}</div>
- <div class="_content">
- <MkSwitch v-model:value="enableEmail" @update:value="save()">{{ $ts.enableEmail }}<template #desc>{{ $ts.emailConfigInfo }}</template></MkSwitch>
- <MkInput v-model:value="email" type="email" :disabled="!enableEmail">{{ $ts.email }}</MkInput>
- <div><b>{{ $ts.smtpConfig }}</b></div>
- <div class="_inputs">
- <MkInput v-model:value="smtpHost" :disabled="!enableEmail">{{ $ts.smtpHost }}</MkInput>
- <MkInput v-model:value="smtpPort" type="number" :disabled="!enableEmail">{{ $ts.smtpPort }}</MkInput>
- </div>
- <div class="_inputs">
- <MkInput v-model:value="smtpUser" :disabled="!enableEmail">{{ $ts.smtpUser }}</MkInput>
- <MkInput v-model:value="smtpPass" type="password" :disabled="!enableEmail">{{ $ts.smtpPass }}</MkInput>
- </div>
- <MkInfo>{{ $ts.emptyToDisableSmtpAuth }}</MkInfo>
- <MkSwitch v-model:value="smtpSecure" :disabled="!enableEmail">{{ $ts.smtpSecure }}<template #desc>{{ $ts.smtpSecureInfo }}</template></MkSwitch>
- <div>
- <MkButton :disabled="!enableEmail" primary inline @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- <MkButton :disabled="!enableEmail" inline @click="testEmail()">{{ $ts.testEmail }}</MkButton>
- </div>
- </div>
- </section>
+ <FormInput v-model:value="maintainerEmail" type="email">
+ <template #prefix><i class="fas fa-envelope"></i></template>
+ <span>{{ $ts.maintainerEmail }}</span>
+ </FormInput>
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faBolt"/> {{ $ts.serviceworker }}</div>
- <div class="_content">
- <MkSwitch v-model:value="enableServiceWorker">{{ $ts.enableServiceworker }}<template #desc>{{ $ts.serviceworkerInfo }}</template></MkSwitch>
- <template v-if="enableServiceWorker">
- <div class="_inputs">
- <MkInput v-model:value="swPublicKey" :disabled="!enableServiceWorker"><template #icon><Fa :icon="faKey"/></template>Public key</MkInput>
- <MkInput v-model:value="swPrivateKey" :disabled="!enableServiceWorker"><template #icon><Fa :icon="faKey"/></template>Private key</MkInput>
- </div>
- </template>
- </div>
- <div class="_footer">
- <MkButton primary @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- </div>
- </section>
+ <FormInput v-model:value="maxNoteTextLength" type="number">
+ <template #prefix><i class="fas fa-pencil-alt"></i></template>
+ <span>{{ $ts.maxNoteTextLength }}</span>
+ </FormInput>
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faThumbtack"/> {{ $ts.pinnedUsers }}</div>
- <div class="_content">
- <MkTextarea v-model:value="pinnedUsers">
- <template #desc>{{ $ts.pinnedUsersDescription }} <button class="_textButton" @click="addPinUser">{{ $ts.addUser }}</button></template>
- </MkTextarea>
- </div>
- <div class="_footer">
- <MkButton primary @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- </div>
- </section>
+ <FormSwitch v-model:value="enableLocalTimeline">{{ $ts.enableLocalTimeline }}</FormSwitch>
+ <FormSwitch v-model:value="enableGlobalTimeline">{{ $ts.enableGlobalTimeline }}</FormSwitch>
+ <FormInfo>{{ $ts.disablingTimelinesInfo }}</FormInfo>
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faThumbtack"/> {{ $ts.pinnedPages }}</div>
- <div class="_content">
- <MkTextarea v-model:value="pinnedPages">
- <template #desc>{{ $ts.pinnedPagesDescription }}</template>
- </MkTextarea>
- </div>
- <div class="_footer">
- <MkButton primary @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- </div>
- </section>
-
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faCloud"/> {{ $ts.files }}</div>
- <div class="_content">
- <MkSwitch v-model:value="cacheRemoteFiles">{{ $ts.cacheRemoteFiles }}<template #desc>{{ $ts.cacheRemoteFilesDescription }}</template></MkSwitch>
- <MkSwitch v-model:value="proxyRemoteFiles">{{ $ts.proxyRemoteFiles }}<template #desc>{{ $ts.proxyRemoteFilesDescription }}</template></MkSwitch>
- <MkInput v-model:value="localDriveCapacityMb" type="number">{{ $ts.driveCapacityPerLocalAccount }}<template #suffix>MB</template><template #desc>{{ $ts.inMb }}</template></MkInput>
- <MkInput v-model:value="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles">{{ $ts.driveCapacityPerRemoteAccount }}<template #suffix>MB</template><template #desc>{{ $ts.inMb }}</template></MkInput>
- </div>
- <div class="_footer">
- <MkButton primary @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- </div>
- </section>
-
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faCloud"/> {{ $ts.objectStorage }}</div>
- <div class="_content">
- <MkSwitch v-model:value="useObjectStorage">{{ $ts.useObjectStorage }}</MkSwitch>
- <template v-if="useObjectStorage">
- <MkInput v-model:value="objectStorageBaseUrl" :disabled="!useObjectStorage">{{ $ts.objectStorageBaseUrl }}<template #desc>{{ $ts.objectStorageBaseUrlDesc }}</template></MkInput>
- <div class="_inputs">
- <MkInput v-model:value="objectStorageBucket" :disabled="!useObjectStorage">{{ $ts.objectStorageBucket }}<template #desc>{{ $ts.objectStorageBucketDesc }}</template></MkInput>
- <MkInput v-model:value="objectStoragePrefix" :disabled="!useObjectStorage">{{ $ts.objectStoragePrefix }}<template #desc>{{ $ts.objectStoragePrefixDesc }}</template></MkInput>
- </div>
- <MkInput v-model:value="objectStorageEndpoint" :disabled="!useObjectStorage">{{ $ts.objectStorageEndpoint }}<template #desc>{{ $ts.objectStorageEndpointDesc }}</template></MkInput>
- <div class="_inputs">
- <MkInput v-model:value="objectStorageRegion" :disabled="!useObjectStorage">{{ $ts.objectStorageRegion }}<template #desc>{{ $ts.objectStorageRegionDesc }}</template></MkInput>
- </div>
- <div class="_inputs">
- <MkInput v-model:value="objectStorageAccessKey" :disabled="!useObjectStorage"><template #icon><Fa :icon="faKey"/></template>Access key</MkInput>
- <MkInput v-model:value="objectStorageSecretKey" :disabled="!useObjectStorage"><template #icon><Fa :icon="faKey"/></template>Secret key</MkInput>
- </div>
- <MkSwitch v-model:value="objectStorageUseSSL" :disabled="!useObjectStorage">{{ $ts.objectStorageUseSSL }}<template #desc>{{ $ts.objectStorageUseSSLDesc }}</template></MkSwitch>
- <MkSwitch v-model:value="objectStorageUseProxy" :disabled="!useObjectStorage">{{ $ts.objectStorageUseProxy }}<template #desc>{{ $ts.objectStorageUseProxyDesc }}</template></MkSwitch>
- <MkSwitch v-model:value="objectStorageSetPublicRead" :disabled="!useObjectStorage">{{ $ts.objectStorageSetPublicRead }}</MkSwitch>
- <MkSwitch v-model:value="objectStorageS3ForcePathStyle" :disabled="!useObjectStorage">s3ForcePathStyle</MkSwitch>
- </template>
- </div>
- <div class="_footer">
- <MkButton primary @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- </div>
- </section>
-
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faGhost"/> {{ $ts.proxyAccount }}</div>
- <div class="_content">
- <MkInput :value="proxyAccount ? proxyAccount.username : null" disabled><template #prefix>@</template>{{ $ts.proxyAccount }}<template #desc>{{ $ts.proxyAccountDescription }}</template></MkInput>
- <MkButton primary @click="chooseProxyAccount">{{ $ts.chooseProxyAccount }}</MkButton>
- </div>
- </section>
-
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faBan"/> {{ $ts.blockedInstances }}</div>
- <div class="_content">
- <MkTextarea v-model:value="blockedHosts">
- <template #desc>{{ $ts.blockedInstancesDescription }}</template>
- </MkTextarea>
- </div>
- <div class="_footer">
- <MkButton primary @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- </div>
- </section>
-
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faShareAlt"/> {{ $ts.integration }}</div>
- <div class="_content">
- <header><Fa :icon="faTwitter"/> Twitter</header>
- <MkSwitch v-model:value="enableTwitterIntegration">{{ $ts.enable }}</MkSwitch>
- <template v-if="enableTwitterIntegration">
- <MkInfo>Callback URL: {{ `${url}/api/tw/cb` }}</MkInfo>
- <MkInput v-model:value="twitterConsumerKey" :disabled="!enableTwitterIntegration"><template #icon><Fa :icon="faKey"/></template>Consumer Key</MkInput>
- <MkInput v-model:value="twitterConsumerSecret" :disabled="!enableTwitterIntegration"><template #icon><Fa :icon="faKey"/></template>Consumer Secret</MkInput>
- </template>
- </div>
- <div class="_content">
- <header><Fa :icon="faGithub"/> GitHub</header>
- <MkSwitch v-model:value="enableGithubIntegration">{{ $ts.enable }}</MkSwitch>
- <template v-if="enableGithubIntegration">
- <MkInfo>Callback URL: {{ `${url}/api/gh/cb` }}</MkInfo>
- <MkInput v-model:value="githubClientId" :disabled="!enableGithubIntegration"><template #icon><Fa :icon="faKey"/></template>Client ID</MkInput>
- <MkInput v-model:value="githubClientSecret" :disabled="!enableGithubIntegration"><template #icon><Fa :icon="faKey"/></template>Client Secret</MkInput>
- </template>
- </div>
- <div class="_content">
- <header><Fa :icon="faDiscord"/> Discord</header>
- <MkSwitch v-model:value="enableDiscordIntegration">{{ $ts.enable }}</MkSwitch>
- <template v-if="enableDiscordIntegration">
- <MkInfo>Callback URL: {{ `${url}/api/dc/cb` }}</MkInfo>
- <MkInput v-model:value="discordClientId" :disabled="!enableDiscordIntegration"><template #icon><Fa :icon="faKey"/></template>Client ID</MkInput>
- <MkInput v-model:value="discordClientSecret" :disabled="!enableDiscordIntegration"><template #icon><Fa :icon="faKey"/></template>Client Secret</MkInput>
- </template>
- </div>
- <div class="_footer">
- <MkButton primary @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- </div>
- </section>
-
- <section class="_card _gap">
- <div class="_title"><Fa :icon="faArchway" /> Summaly Proxy</div>
- <div class="_content">
- <MkInput v-model:value="summalyProxy">URL</MkInput>
- <MkButton primary @click="save(true)"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- </div>
- </section>
-</div>
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ </FormSuspense>
+</FormBase>
</template>
<script lang="ts">
-import { defineComponent, defineAsyncComponent } from 'vue';
-import { faPencilAlt, faShareAlt, faGhost, faCog, faPlus, faCloud, faInfoCircle, faBan, faSave, faServer, faLink, faThumbtack, faUser, faShieldAlt, faKey, faBolt, faArchway } from '@fortawesome/free-solid-svg-icons';
-import { faTrashAlt, faEnvelope } from '@fortawesome/free-regular-svg-icons';
-import { faTwitter, faDiscord, faGithub } from '@fortawesome/free-brands-svg-icons';
-import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
-import MkInfo from '@client/components/ui/info.vue';
-import { url } from '@client/config';
-import getAcct from '@/misc/acct/render';
+import { defineComponent } from 'vue';
+import FormSwitch from '@client/components/form/switch.vue';
+import FormInput from '@client/components/form/input.vue';
+import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormTextarea from '@client/components/form/textarea.vue';
+import FormInfo from '@client/components/form/info.vue';
+import FormSuspense from '@client/components/form/suspense.vue';
import * as os from '@client/os';
-import { fetchInstance } from '@client/instance';
import * as symbols from '@client/symbols';
+import { fetchInstance } from '@client/instance';
export default defineComponent({
components: {
- MkButton,
- MkInput,
- MkTextarea,
- MkSwitch,
- MkInfo,
- Captcha: defineAsyncComponent(() => import('@client/components/captcha.vue')),
+ FormSwitch,
+ FormInput,
+ FormBase,
+ FormGroup,
+ FormButton,
+ FormTextarea,
+ FormInfo,
+ FormSuspense,
},
+ emits: ['info'],
+
data() {
return {
[symbols.PAGE_INFO]: {
- title: this.$ts.instance,
- icon: faCog,
+ title: this.$ts.general,
+ icon: 'fas fa-cog'
},
- meta: null,
- url,
- proxyAccount: null,
- proxyAccountId: null,
- cacheRemoteFiles: false,
- proxyRemoteFiles: false,
- localDriveCapacityMb: 0,
- remoteDriveCapacityMb: 0,
- blockedHosts: '',
- pinnedUsers: '',
- pinnedPages: '',
- pinnedClipId: null,
- maintainerName: null,
- maintainerEmail: null,
name: null,
description: null,
tosUrl: null as string | null,
- enableEmail: false,
- email: null,
- bannerUrl: null,
+ maintainerName: null,
+ maintainerEmail: null,
iconUrl: null,
- logoImageUrl: null,
- backgroundImageUrl: null,
+ bannerUrl: null,
maxNoteTextLength: 0,
- enableRegistration: false,
enableLocalTimeline: false,
enableGlobalTimeline: false,
- enableHcaptcha: false,
- hcaptchaSiteKey: null,
- hcaptchaSecretKey: null,
- enableRecaptcha: false,
- recaptchaSiteKey: null,
- recaptchaSecretKey: null,
- enableServiceWorker: false,
- swPublicKey: null,
- swPrivateKey: null,
- useObjectStorage: false,
- objectStorageBaseUrl: null,
- objectStorageBucket: null,
- objectStoragePrefix: null,
- objectStorageEndpoint: null,
- objectStorageRegion: null,
- objectStoragePort: null,
- objectStorageAccessKey: null,
- objectStorageSecretKey: null,
- objectStorageUseSSL: false,
- objectStorageUseProxy: false,
- objectStorageSetPublicRead: false,
- objectStorageS3ForcePathStyle: true,
- enableTwitterIntegration: false,
- twitterConsumerKey: null,
- twitterConsumerSecret: null,
- enableGithubIntegration: false,
- githubClientId: null,
- githubClientSecret: null,
- enableDiscordIntegration: false,
- discordClientId: null,
- discordClientSecret: null,
- useStarForReactionFallback: false,
- smtpSecure: false,
- smtpHost: '',
- smtpPort: 0,
- smtpUser: '',
- smtpPass: '',
- summalyProxy: '',
- faPencilAlt, faTwitter, faDiscord, faGithub, faShareAlt, faTrashAlt, faGhost, faCog, faPlus, faCloud, faInfoCircle, faBan, faSave, faServer, faLink, faEnvelope, faThumbtack, faUser, faShieldAlt, faKey, faBolt, faArchway
- }
- },
-
- async created() {
- this.meta = await os.api('meta', { detail: true });
-
- this.name = this.meta.name;
- this.description = this.meta.description;
- this.tosUrl = this.meta.tosUrl;
- this.bannerUrl = this.meta.bannerUrl;
- this.iconUrl = this.meta.iconUrl;
- this.logoImageUrl = this.meta.logoImageUrl;
- this.backgroundImageUrl = this.meta.backgroundImageUrl;
- this.enableEmail = this.meta.enableEmail;
- this.email = this.meta.email;
- this.maintainerName = this.meta.maintainerName;
- this.maintainerEmail = this.meta.maintainerEmail;
- this.maxNoteTextLength = this.meta.maxNoteTextLength;
- this.enableRegistration = !this.meta.disableRegistration;
- this.enableLocalTimeline = !this.meta.disableLocalTimeline;
- this.enableGlobalTimeline = !this.meta.disableGlobalTimeline;
- this.enableHcaptcha = this.meta.enableHcaptcha;
- this.hcaptchaSiteKey = this.meta.hcaptchaSiteKey;
- this.hcaptchaSecretKey = this.meta.hcaptchaSecretKey;
- this.enableRecaptcha = this.meta.enableRecaptcha;
- this.recaptchaSiteKey = this.meta.recaptchaSiteKey;
- this.recaptchaSecretKey = this.meta.recaptchaSecretKey;
- this.proxyAccountId = this.meta.proxyAccountId;
- this.cacheRemoteFiles = this.meta.cacheRemoteFiles;
- this.proxyRemoteFiles = this.meta.proxyRemoteFiles;
- this.localDriveCapacityMb = this.meta.driveCapacityPerLocalUserMb;
- this.remoteDriveCapacityMb = this.meta.driveCapacityPerRemoteUserMb;
- this.blockedHosts = this.meta.blockedHosts.join('\n');
- this.pinnedUsers = this.meta.pinnedUsers.join('\n');
- this.pinnedPages = this.meta.pinnedPages.join('\n');
- this.pinnedClipId = this.meta.pinnedClipId;
- this.enableServiceWorker = this.meta.enableServiceWorker;
- this.swPublicKey = this.meta.swPublickey;
- this.swPrivateKey = this.meta.swPrivateKey;
- this.useObjectStorage = this.meta.useObjectStorage;
- this.objectStorageBaseUrl = this.meta.objectStorageBaseUrl;
- this.objectStorageBucket = this.meta.objectStorageBucket;
- this.objectStoragePrefix = this.meta.objectStoragePrefix;
- this.objectStorageEndpoint = this.meta.objectStorageEndpoint;
- this.objectStorageRegion = this.meta.objectStorageRegion;
- this.objectStoragePort = this.meta.objectStoragePort;
- this.objectStorageAccessKey = this.meta.objectStorageAccessKey;
- this.objectStorageSecretKey = this.meta.objectStorageSecretKey;
- this.objectStorageUseSSL = this.meta.objectStorageUseSSL;
- this.objectStorageUseProxy = this.meta.objectStorageUseProxy;
- this.objectStorageSetPublicRead = this.meta.objectStorageSetPublicRead;
- this.objectStorageS3ForcePathStyle = this.meta.objectStorageS3ForcePathStyle;
- this.enableTwitterIntegration = this.meta.enableTwitterIntegration;
- this.twitterConsumerKey = this.meta.twitterConsumerKey;
- this.twitterConsumerSecret = this.meta.twitterConsumerSecret;
- this.enableGithubIntegration = this.meta.enableGithubIntegration;
- this.githubClientId = this.meta.githubClientId;
- this.githubClientSecret = this.meta.githubClientSecret;
- this.enableDiscordIntegration = this.meta.enableDiscordIntegration;
- this.discordClientId = this.meta.discordClientId;
- this.discordClientSecret = this.meta.discordClientSecret;
- this.useStarForReactionFallback = this.meta.useStarForReactionFallback;
- this.smtpSecure = this.meta.smtpSecure;
- this.smtpHost = this.meta.smtpHost;
- this.smtpPort = this.meta.smtpPort;
- this.smtpUser = this.meta.smtpUser;
- this.smtpPass = this.meta.smtpPass;
- this.summalyProxy = this.meta.summalyProxy;
-
- if (this.proxyAccountId) {
- os.api('users/show', { userId: this.proxyAccountId }).then(proxyAccount => {
- this.proxyAccount = proxyAccount;
- });
}
},
- mounted() {
- this.$watch('enableHcaptcha', () => {
- if (this.enableHcaptcha && this.enableRecaptcha) {
- os.dialog({
- type: 'question', // warning だと間違って cancel するかもしれない
- showCancelButton: true,
- title: this.$ts.settingGuide,
- text: this.$ts.avoidMultiCaptchaConfirm,
- }).then(({ canceled }) => {
- if (canceled) {
- return;
- }
-
- this.enableRecaptcha = false;
- });
- }
- });
-
- this.$watch('enableRecaptcha', () => {
- if (this.enableRecaptcha && this.enableHcaptcha) {
- os.dialog({
- type: 'question', // warning だと間違って cancel するかもしれない
- showCancelButton: true,
- title: this.$ts.settingGuide,
- text: this.$ts.avoidMultiCaptchaConfirm,
- }).then(({ canceled }) => {
- if (canceled) {
- return;
- }
-
- this.enableHcaptcha = false;
- });
- }
- });
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
},
methods: {
- invite() {
- os.api('admin/invite').then(x => {
- os.dialog({
- type: 'info',
- text: x.code
- });
- }).catch(e => {
- os.dialog({
- type: 'error',
- text: e
- });
- });
- },
-
- addPinUser() {
- os.selectUser().then(user => {
- this.pinnedUsers = this.pinnedUsers.trim();
- this.pinnedUsers += '\n@' + getAcct(user);
- this.pinnedUsers = this.pinnedUsers.trim();
- });
+ async init() {
+ const meta = await os.api('meta', { detail: true });
+ this.name = meta.name;
+ this.description = meta.description;
+ this.tosUrl = meta.tosUrl;
+ this.iconUrl = meta.iconUrl;
+ this.bannerUrl = meta.bannerUrl;
+ this.maintainerName = meta.maintainerName;
+ this.maintainerEmail = meta.maintainerEmail;
+ this.maxNoteTextLength = meta.maxNoteTextLength;
+ this.enableLocalTimeline = !meta.disableLocalTimeline;
+ this.enableGlobalTimeline = !meta.disableGlobalTimeline;
},
- chooseProxyAccount() {
- os.selectUser().then(user => {
- this.proxyAccount = user;
- this.proxyAccountId = user.id;
- this.save(true);
- });
- },
-
- async testEmail() {
- os.api('admin/send-email', {
- to: this.maintainerEmail,
- subject: 'Test email',
- text: 'Yo'
- }).then(x => {
- os.dialog({
- type: 'success',
- splash: true
- });
- }).catch(e => {
- os.dialog({
- type: 'error',
- text: e
- });
- });
- },
-
- save(withDialog = false) {
- os.api('admin/update-meta', {
+ save() {
+ os.apiWithDialog('admin/update-meta', {
name: this.name,
description: this.description,
tosUrl: this.tosUrl,
- bannerUrl: this.bannerUrl,
iconUrl: this.iconUrl,
- logoImageUrl: this.logoImageUrl,
- backgroundImageUrl: this.backgroundImageUrl,
+ bannerUrl: this.bannerUrl,
maintainerName: this.maintainerName,
maintainerEmail: this.maintainerEmail,
maxNoteTextLength: this.maxNoteTextLength,
- disableRegistration: !this.enableRegistration,
disableLocalTimeline: !this.enableLocalTimeline,
disableGlobalTimeline: !this.enableGlobalTimeline,
- enableHcaptcha: this.enableHcaptcha,
- hcaptchaSiteKey: this.hcaptchaSiteKey,
- hcaptchaSecretKey: this.hcaptchaSecretKey,
- enableRecaptcha: this.enableRecaptcha,
- recaptchaSiteKey: this.recaptchaSiteKey,
- recaptchaSecretKey: this.recaptchaSecretKey,
- proxyAccountId: this.proxyAccountId,
- cacheRemoteFiles: this.cacheRemoteFiles,
- proxyRemoteFiles: this.proxyRemoteFiles,
- localDriveCapacityMb: parseInt(this.localDriveCapacityMb, 10),
- remoteDriveCapacityMb: parseInt(this.remoteDriveCapacityMb, 10),
- blockedHosts: this.blockedHosts.split('\n') || [],
- pinnedUsers: this.pinnedUsers ? this.pinnedUsers.split('\n') : [],
- pinnedPages: this.pinnedPages ? this.pinnedPages.split('\n') : [],
- pinnedClipId: (this.pinnedClipId && this.pinnedClipId) != '' ? this.pinnedClipId : null,
- enableServiceWorker: this.enableServiceWorker,
- swPublicKey: this.swPublicKey,
- swPrivateKey: this.swPrivateKey,
- useObjectStorage: this.useObjectStorage,
- objectStorageBaseUrl: this.objectStorageBaseUrl ? this.objectStorageBaseUrl : null,
- objectStorageBucket: this.objectStorageBucket ? this.objectStorageBucket : null,
- objectStoragePrefix: this.objectStoragePrefix ? this.objectStoragePrefix : null,
- objectStorageEndpoint: this.objectStorageEndpoint ? this.objectStorageEndpoint : null,
- objectStorageRegion: this.objectStorageRegion ? this.objectStorageRegion : null,
- objectStoragePort: this.objectStoragePort ? this.objectStoragePort : null,
- objectStorageAccessKey: this.objectStorageAccessKey ? this.objectStorageAccessKey : null,
- objectStorageSecretKey: this.objectStorageSecretKey ? this.objectStorageSecretKey : null,
- objectStorageUseSSL: this.objectStorageUseSSL,
- objectStorageUseProxy: this.objectStorageUseProxy,
- objectStorageSetPublicRead: this.objectStorageSetPublicRead,
- objectStorageS3ForcePathStyle: this.objectStorageS3ForcePathStyle,
- enableTwitterIntegration: this.enableTwitterIntegration,
- twitterConsumerKey: this.twitterConsumerKey,
- twitterConsumerSecret: this.twitterConsumerSecret,
- enableGithubIntegration: this.enableGithubIntegration,
- githubClientId: this.githubClientId,
- githubClientSecret: this.githubClientSecret,
- enableDiscordIntegration: this.enableDiscordIntegration,
- discordClientId: this.discordClientId,
- discordClientSecret: this.discordClientSecret,
- enableEmail: this.enableEmail,
- email: this.email,
- smtpSecure: this.smtpSecure,
- smtpHost: this.smtpHost,
- smtpPort: this.smtpPort,
- smtpUser: this.smtpUser,
- smtpPass: this.smtpPass,
- summalyProxy: this.summalyProxy,
- useStarForReactionFallback: this.useStarForReactionFallback,
}).then(() => {
fetchInstance();
- if (withDialog) {
- os.success();
- }
- }).catch(e => {
- os.dialog({
- type: 'error',
- text: e
- });
});
}
}
diff --git a/src/client/pages/instance/user-dialog.vue b/src/client/pages/instance/user-dialog.vue
deleted file mode 100644
index a6bab5ecb8..0000000000
--- a/src/client/pages/instance/user-dialog.vue
+++ /dev/null
@@ -1,233 +0,0 @@
-<template>
-<XModalWindow ref="dialog"
- :width="370"
- @close="$refs.dialog.close()"
- @closed="$emit('closed')"
->
- <template #header v-if="user"><MkUserName class="name" :user="user"/></template>
- <div class="vrcsvlkm" v-if="user && info">
- <div class="_section">
- <div class="banner" :style="bannerStyle">
- <MkAvatar class="avatar" :user="user" :show-indicator="true"/>
- </div>
- </div>
- <div class="_section">
- <div class="title">
- <span class="acct">@{{ acct(user) }}</span>
- </div>
- <div class="status">
- <span class="staff" v-if="user.isAdmin"><Fa :icon="faBookmark"/></span>
- <span class="staff" v-if="user.isModerator"><Fa :icon="farBookmark"/></span>
- <span class="punished" v-if="user.isSilenced"><Fa :icon="faMicrophoneSlash"/></span>
- <span class="punished" v-if="user.isSuspended"><Fa :icon="faSnowflake"/></span>
- </div>
- </div>
- <div class="_section">
- <div class="_content">
- <MkSwitch v-if="user.host == null && $i.isAdmin && (moderator || !user.isAdmin)" @update:value="toggleModerator" v-model:value="moderator">{{ $ts.moderator }}</MkSwitch>
- <MkSwitch @update:value="toggleSilence" v-model:value="silenced">{{ $ts.silence }}</MkSwitch>
- <MkSwitch @update:value="toggleSuspend" v-model:value="suspended">{{ $ts.suspend }}</MkSwitch>
- </div>
- </div>
- <div class="_section">
- <div class="_content">
- <MkButton full @click="openProfile"><Fa :icon="faExternalLinkSquareAlt"/> {{ $ts.profile }}</MkButton>
- <MkButton full v-if="user.host != null" @click="updateRemoteUser"><Fa :icon="faSync"/> {{ $ts.updateRemoteUser }}</MkButton>
- <MkButton full @click="resetPassword"><Fa :icon="faKey"/> {{ $ts.resetPassword }}</MkButton>
- <MkButton full @click="deleteAllFiles" danger><Fa :icon="faTrashAlt"/> {{ $ts.deleteAllFiles }}</MkButton>
- </div>
- </div>
- <div class="_section">
- <details class="_content rawdata">
- <pre><code>{{ JSON.stringify(info, null, 2) }}</code></pre>
- </details>
- </div>
- </div>
-</XModalWindow>
-</template>
-
-<script lang="ts">
-import { computed, defineComponent } from 'vue';
-import { faTimes, faBookmark, faKey, faSync, faMicrophoneSlash, faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
-import { faSnowflake, faTrashAlt, faBookmark as farBookmark } from '@fortawesome/free-regular-svg-icons';
-import MkButton from '@client/components/ui/button.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
-import XModalWindow from '@client/components/ui/modal-window.vue';
-import Progress from '@client/scripts/loading';
-import { acct, userPage } from '../../filters/user';
-import * as os from '@client/os';
-
-export default defineComponent({
- components: {
- MkButton,
- MkSwitch,
- XModalWindow,
- },
-
- props: {
- userId: {
- required: true,
- }
- },
-
- emits: ['closed'],
-
- data() {
- return {
- user: null,
- info: null,
- moderator: false,
- silenced: false,
- suspended: false,
- faTimes, faBookmark, farBookmark, faKey, faSync, faMicrophoneSlash, faSnowflake, faTrashAlt, faExternalLinkSquareAlt
- };
- },
-
- computed: {
- bannerStyle(): any {
- if (this.user.bannerUrl == null) return {};
- return {
- backgroundImage: `url(${ this.user.bannerUrl })`
- };
- },
- },
-
- created() {
- this.fetch();
- },
-
- methods: {
- async fetch() {
- Progress.start();
- this.user = await os.api('users/show', { userId: this.userId });
- this.info = await os.api('admin/show-user', { userId: this.userId });
- this.moderator = this.info.isModerator;
- this.silenced = this.info.isSilenced;
- this.suspended = this.info.isSuspended;
- Progress.done();
- },
-
- /** 処理対象ユーザーの情報を更新する */
- async refreshUser() {
- this.user = await os.api('users/show', { userId: this.user.id });
- this.info = await os.api('admin/show-user', { userId: this.user.id });
- },
-
- openProfile() {
- window.open(userPage(this.user, null, true), '_blank');
- },
-
- async updateRemoteUser() {
- await os.api('admin/update-remote-user', { userId: this.user.id }).then(res => {
- os.success();
- });
- await this.refreshUser();
- },
-
- async resetPassword() {
- os.apiWithDialog('admin/reset-password', {
- userId: this.user.id,
- }, undefined, ({ password }) => {
- os.dialog({
- type: 'success',
- text: this.$t('newPasswordIs', { password })
- });
- });
- },
-
- async toggleSilence(v) {
- const confirm = await os.dialog({
- type: 'warning',
- showCancelButton: true,
- text: v ? this.$ts.silenceConfirm : this.$ts.unsilenceConfirm,
- });
- if (confirm.canceled) {
- this.silenced = !v;
- } else {
- await os.api(v ? 'admin/silence-user' : 'admin/unsilence-user', { userId: this.user.id });
- await this.refreshUser();
- }
- },
-
- async toggleSuspend(v) {
- const confirm = await os.dialog({
- type: 'warning',
- showCancelButton: true,
- text: v ? this.$ts.suspendConfirm : this.$ts.unsuspendConfirm,
- });
- if (confirm.canceled) {
- this.suspended = !v;
- } else {
- await os.api(v ? 'admin/suspend-user' : 'admin/unsuspend-user', { userId: this.user.id });
- await this.refreshUser();
- }
- },
-
- async toggleModerator(v) {
- await os.api(v ? 'admin/moderators/add' : 'admin/moderators/remove', { userId: this.user.id });
- await this.refreshUser();
- },
-
- async deleteAllFiles() {
- const confirm = await os.dialog({
- type: 'warning',
- showCancelButton: true,
- text: this.$ts.deleteAllFilesConfirm,
- });
- if (confirm.canceled) return;
- const process = async () => {
- await os.api('admin/delete-all-files-of-a-user', { userId: this.user.id });
- os.success();
- };
- await process().catch(e => {
- os.dialog({
- type: 'error',
- text: e.toString()
- });
- });
- await this.refreshUser();
- },
-
- acct
- }
-});
-</script>
-
-<style lang="scss" scoped>
-.vrcsvlkm {
- > ._section {
- > .banner {
- position: relative;
- height: 100px;
- background-color: #4c5e6d;
- background-size: cover;
- background-position: center;
- border-radius: 8px;
-
- > .avatar {
- position: absolute;
- top: 60px;
- width: 64px;
- height: 64px;
- left: 0;
- right: 0;
- margin: 0 auto;
- border: solid 4px var(--panel);
- }
- }
-
- > .title {
- text-align: center;
- }
-
- > .status {
- text-align: center;
- margin-top: 8px;
- }
-
- > .rawdata {
- overflow: auto;
- }
- }
-}
-</style>
diff --git a/src/client/pages/instance/users.vue b/src/client/pages/instance/users.vue
index ea09b1bda0..2808b70fba 100644
--- a/src/client/pages/instance/users.vue
+++ b/src/client/pages/instance/users.vue
@@ -1,88 +1,71 @@
<template>
-<div class="mk-instance-users">
- <div class="_section">
- <div class="_content">
- <MkButton inline primary @click="addUser()"><Fa :icon="faPlus"/> {{ $ts.addUser }}</MkButton>
- </div>
+<div class="lknzcolw">
+ <div class="actions">
+ <MkButton inline primary @click="addUser()"><i class="fas fa-plus"></i> {{ $ts.addUser }}</MkButton>
+ <MkButton inline primary @click="lookupUser()"><i class="fas fa-search"></i> {{ $ts.lookup }}</MkButton>
</div>
- <div class="_section lookup">
- <div class="_title"><Fa :icon="faSearch"/> {{ $ts.lookup }}</div>
- <div class="_content">
- <MkInput class="target" v-model:value="target" type="text" @enter="showUser()">
- <span>{{ $ts.usernameOrUserId }}</span>
+ <div class="users">
+ <div class="inputs" style="display: flex;">
+ <MkSelect v-model:value="sort" style="margin: 0; 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:value="state" style="margin: 0; flex: 1;">
+ <template #label>{{ $ts.state }}</template>
+ <option value="all">{{ $ts.all }}</option>
+ <option value="available">{{ $ts.normal }}</option>
+ <option value="admin">{{ $ts.administrator }}</option>
+ <option value="moderator">{{ $ts.moderator }}</option>
+ <option value="silenced">{{ $ts.silence }}</option>
+ <option value="suspended">{{ $ts.suspend }}</option>
+ </MkSelect>
+ <MkSelect v-model:value="origin" style="margin: 0; 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:value="searchUsername" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:value="$refs.users.reload()">
+ <span>{{ $ts.username }}</span>
+ </MkInput>
+ <MkInput v-model:value="searchHost" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:value="$refs.users.reload()" :disabled="pagination.params().origin === 'local'">
+ <span>{{ $ts.host }}</span>
</MkInput>
- <MkButton @click="showUser()" primary><Fa :icon="faSearch"/> {{ $ts.lookup }}</MkButton>
</div>
- </div>
- <div class="_section users">
- <div class="_title"><Fa :icon="faUsers"/> {{ $ts.users }}</div>
- <div class="_content">
- <div class="inputs" style="display: flex;">
- <MkSelect v-model:value="sort" style="margin: 0; 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:value="state" style="margin: 0; flex: 1;">
- <template #label>{{ $ts.state }}</template>
- <option value="all">{{ $ts.all }}</option>
- <option value="available">{{ $ts.normal }}</option>
- <option value="admin">{{ $ts.administrator }}</option>
- <option value="moderator">{{ $ts.moderator }}</option>
- <option value="silenced">{{ $ts.silence }}</option>
- <option value="suspended">{{ $ts.suspend }}</option>
- </MkSelect>
- <MkSelect v-model:value="origin" style="margin: 0; 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:value="searchUsername" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:value="$refs.users.reload()">
- <span>{{ $ts.username }}</span>
- </MkInput>
- <MkInput v-model:value="searchHost" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:value="$refs.users.reload()" :disabled="pagination.params().origin === 'local'">
- <span>{{ $ts.host }}</span>
- </MkInput>
- </div>
-
- <MkPagination :pagination="pagination" #default="{items}" class="users" ref="users">
- <button class="user _panel _button _gap" v-for="user in items" :key="user.id" @click="show(user)">
- <MkAvatar class="avatar" :user="user" :disable-link="true" :show-indicator="true"/>
- <div class="body">
- <header>
- <MkUserName class="name" :user="user"/>
- <span class="acct">@{{ acct(user) }}</span>
- <span class="staff" v-if="user.isAdmin"><Fa :icon="faBookmark"/></span>
- <span class="staff" v-if="user.isModerator"><Fa :icon="farBookmark"/></span>
- <span class="punished" v-if="user.isSilenced"><Fa :icon="faMicrophoneSlash"/></span>
- <span class="punished" v-if="user.isSuspended"><Fa :icon="faSnowflake"/></span>
- </header>
- <div>
- <span>{{ $ts.lastUsed }}: <MkTime v-if="user.updatedAt" :time="user.updatedAt" mode="detail"/></span>
- </div>
- <div>
- <span>{{ $ts.registeredDate }}: <MkTime :time="user.createdAt" mode="detail"/></span>
- </div>
+ <MkPagination :pagination="pagination" #default="{items}" class="users" ref="users">
+ <button class="user _panel _button _gap" v-for="user in items" :key="user.id" @click="show(user)">
+ <MkAvatar class="avatar" :user="user" :disable-link="true" :show-indicator="true"/>
+ <div class="body">
+ <header>
+ <MkUserName class="name" :user="user"/>
+ <span class="acct">@{{ acct(user) }}</span>
+ <span class="staff" v-if="user.isAdmin"><i class="fas fa-bookmark"></i></span>
+ <span class="staff" v-if="user.isModerator"><i class="far fa-bookmark"></i></span>
+ <span class="punished" v-if="user.isSilenced"><i class="fas fa-microphone-slash"></i></span>
+ <span class="punished" v-if="user.isSuspended"><i class="fas fa-snowflake"></i></span>
+ </header>
+ <div>
+ <span>{{ $ts.lastUsed }}: <MkTime v-if="user.updatedAt" :time="user.updatedAt" mode="detail"/></span>
</div>
- </button>
- </MkPagination>
- </div>
+ <div>
+ <span>{{ $ts.registeredDate }}: <MkTime :time="user.createdAt" mode="detail"/></span>
+ </div>
+ </div>
+ </button>
+ </MkPagination>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPlus, faUsers, faSearch, faBookmark, faMicrophoneSlash } from '@fortawesome/free-solid-svg-icons';
-import { faSnowflake, faBookmark as farBookmark } from '@fortawesome/free-regular-svg-icons';
-import parseAcct from '@/misc/acct/parse';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
import MkSelect from '@client/components/ui/select.vue';
@@ -90,6 +73,7 @@ import MkPagination from '@client/components/ui/pagination.vue';
import { acct } from '../../filters/user';
import * as os from '@client/os';
import * as symbols from '@client/symbols';
+import { lookupUser } from '@client/scripts/lookup-user';
export default defineComponent({
components: {
@@ -99,17 +83,18 @@ export default defineComponent({
MkPagination,
},
+ emits: ['info'],
+
data() {
return {
[symbols.PAGE_INFO]: {
title: this.$ts.users,
- icon: faUsers,
+ icon: 'fas fa-users',
action: {
- icon: faSearch,
+ icon: 'fas fa-search',
handler: this.searchUser
}
},
- target: '',
sort: '+createdAt',
state: 'all',
origin: 'local',
@@ -127,7 +112,6 @@ export default defineComponent({
}),
offsetMode: true
},
- faPlus, faUsers, faSearch, faBookmark, farBookmark, faMicrophoneSlash, faSnowflake
}
},
@@ -143,40 +127,12 @@ export default defineComponent({
},
},
- methods: {
- /** テキストエリアのユーザーを解決する */
- fetchUser() {
- return new Promise((res) => {
- const usernamePromise = os.api('users/show', parseAcct(this.target));
- const idPromise = os.api('users/show', { userId: this.target });
- let _notFound = false;
- const notFound = () => {
- if (_notFound) {
- os.dialog({
- type: 'error',
- text: this.$ts.noSuchUser
- });
- } else {
- _notFound = true;
- }
- };
- usernamePromise.then(res).catch(e => {
- if (e.code === 'NO_SUCH_USER') {
- notFound();
- }
- });
- idPromise.then(res).catch(e => {
- notFound();
- });
- });
- },
+ async mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
- /** テキストエリアから処理対象ユーザーを設定する */
- async showUser() {
- const user = await this.fetchUser();
- this.show(user);
- this.target = '';
- },
+ methods: {
+ lookupUser,
searchUser() {
os.selectUser().then(user => {
@@ -206,9 +162,7 @@ export default defineComponent({
},
show(user) {
- os.popup(import('./user-dialog.vue'), {
- userId: user.id
- }, {}, 'closed');
+ os.pageWindow(`/user-info/${user.id}`);
},
acct
@@ -217,57 +171,61 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
-.mk-instance-users {
+.lknzcolw {
+ > .actions {
+ margin: var(--margin);
+ }
+
> .users {
- > ._content {
- > .users {
- margin-top: var(--margin);
+ margin: var(--margin);
+
+ > .users {
+ margin-top: var(--margin);
- > .user {
- display: flex;
- width: 100%;
- box-sizing: border-box;
- text-align: left;
- align-items: center;
- padding: 16px;
+ > .user {
+ display: flex;
+ width: 100%;
+ box-sizing: border-box;
+ text-align: left;
+ align-items: center;
+ padding: 16px;
- &:hover {
- color: var(--accent);
- }
+ &:hover {
+ color: var(--accent);
+ }
- > .avatar {
- width: 60px;
- height: 60px;
- }
+ > .avatar {
+ width: 60px;
+ height: 60px;
+ }
- > .body {
- margin-left: 0.3em;
- padding: 0 8px;
- flex: 1;
+ > .body {
+ margin-left: 0.3em;
+ padding: 0 8px;
+ flex: 1;
- @media (max-width: 500px) {
- font-size: 14px;
- }
+ @media (max-width: 500px) {
+ font-size: 14px;
+ }
- > header {
- > .name {
- font-weight: bold;
- }
+ > header {
+ > .name {
+ font-weight: bold;
+ }
- > .acct {
- margin-left: 8px;
- opacity: 0.7;
- }
+ > .acct {
+ margin-left: 8px;
+ opacity: 0.7;
+ }
- > .staff {
- margin-left: 0.5em;
- color: var(--badge);
- }
+ > .staff {
+ margin-left: 0.5em;
+ color: var(--badge);
+ }
- > .punished {
- margin-left: 0.5em;
- color: #4dabf7;
- }
+ > .punished {
+ margin-left: 0.5em;
+ color: #4dabf7;
}
}
}
diff --git a/src/client/pages/mentions.vue b/src/client/pages/mentions.vue
index 042c3a498b..a12993ebb8 100644
--- a/src/client/pages/mentions.vue
+++ b/src/client/pages/mentions.vue
@@ -6,7 +6,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faAt } from '@fortawesome/free-solid-svg-icons';
import Progress from '@client/scripts/loading';
import XNotes from '@client/components/notes.vue';
import * as symbols from '@client/symbols';
@@ -20,7 +19,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.mentions,
- icon: faAt
+ icon: 'fas fa-at'
},
pagination: {
endpoint: 'notes/mentions',
diff --git a/src/client/pages/messages.vue b/src/client/pages/messages.vue
index 09d92e51ba..6ac9746d4e 100644
--- a/src/client/pages/messages.vue
+++ b/src/client/pages/messages.vue
@@ -6,7 +6,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faEnvelope } from '@fortawesome/free-solid-svg-icons';
import Progress from '@client/scripts/loading';
import XNotes from '@client/components/notes.vue';
import * as symbols from '@client/symbols';
@@ -20,7 +19,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.directNotes,
- icon: faEnvelope
+ icon: 'fas fa-envelope'
},
pagination: {
endpoint: 'notes/mentions',
@@ -29,7 +28,6 @@ export default defineComponent({
visibility: 'specified'
})
},
- faEnvelope
};
},
diff --git a/src/client/pages/messaging/index.vue b/src/client/pages/messaging/index.vue
index 1e316e9090..9f3323f629 100644
--- a/src/client/pages/messaging/index.vue
+++ b/src/client/pages/messaging/index.vue
@@ -1,6 +1,6 @@
<template>
<div class="yweeujhr _root" v-size="{ max: [400] }">
- <MkButton @click="start" primary class="start"><Fa :icon="faPlus"/> {{ $ts.startMessaging }}</MkButton>
+ <MkButton @click="start" primary class="start"><i class="fas fa-plus"></i> {{ $ts.startMessaging }}</MkButton>
<div class="history" v-if="messages.length > 0">
<MkA v-for="(message, i) in messages"
@@ -38,7 +38,6 @@
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
-import { faUser, faUsers, faComments, faPlus } from '@fortawesome/free-solid-svg-icons';
import getAcct from '@/misc/acct/render';
import MkButton from '@client/components/ui/button.vue';
import { acct } from '../../filters/user';
@@ -54,13 +53,12 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.messaging,
- icon: faComments
+ icon: 'fas fa-comments'
},
fetching: true,
moreFetching: false,
messages: [],
connection: null,
- faUser, faUsers, faComments, faPlus
};
},
@@ -120,11 +118,11 @@ export default defineComponent({
start(ev) {
os.modalMenu([{
text: this.$ts.messagingWithUser,
- icon: faUser,
+ icon: 'fas fa-user',
action: () => { this.startUser() }
}, {
text: this.$ts.messagingWithGroup,
- icon: faUsers,
+ icon: 'fas fa-users',
action: () => { this.startGroup() }
}], ev.currentTarget || ev.target);
},
diff --git a/src/client/pages/messaging/messaging-room.form.vue b/src/client/pages/messaging/messaging-room.form.vue
index c547e18850..31c42e4ab3 100644
--- a/src/client/pages/messaging/messaging-room.form.vue
+++ b/src/client/pages/messaging/messaging-room.form.vue
@@ -13,17 +13,16 @@
></textarea>
<div class="file" @click="file = null" v-if="file">{{ file.name }}</div>
<button class="send _button" @click="send" :disabled="!canSend || sending" :title="$ts.send">
- <template v-if="!sending"><Fa :icon="faPaperPlane"/></template><template v-if="sending"><Fa icon="spinner .spin"/></template>
+ <template v-if="!sending"><i class="fas fa-paper-plane"></i></template><template v-if="sending"><i class="fas fa-spinner fa-pulse fa-fw"></i></template>
</button>
- <button class="_button" @click="chooseFile"><Fa :icon="faPhotoVideo"/></button>
- <button class="_button" @click="insertEmoji"><Fa :icon="faLaughSquint"/></button>
+ <button class="_button" @click="chooseFile"><i class="fas fa-photo-video"></i></button>
+ <button class="_button" @click="insertEmoji"><i class="fas fa-laugh-squint"></i></button>
<input ref="file" type="file" @change="onChangeFile"/>
</div>
</template>
<script lang="ts">
import { defineComponent, defineAsyncComponent } from 'vue';
-import { faPaperPlane, faPhotoVideo, faLaughSquint } from '@fortawesome/free-solid-svg-icons';
import insertTextAtCursor from 'insert-text-at-cursor';
import * as autosize from 'autosize';
import { formatTimeString } from '@/misc/format-time-string';
@@ -51,7 +50,6 @@ export default defineComponent({
typing: throttle(3000, () => {
os.stream.send('typingOnMessaging', this.user ? { partner: this.user.id } : { group: this.group.id });
}),
- faPaperPlane, faPhotoVideo, faLaughSquint
};
},
computed: {
diff --git a/src/client/pages/messaging/messaging-room.message.vue b/src/client/pages/messaging/messaging-room.message.vue
index 1228baff68..dfac83ad6a 100644
--- a/src/client/pages/messaging/messaging-room.message.vue
+++ b/src/client/pages/messaging/messaging-room.message.vue
@@ -29,7 +29,7 @@
<span class="read" v-if="isMe && message.isRead">{{ $ts.messageRead }}</span>
</template>
<MkTime :time="message.createdAt"/>
- <template v-if="message.is_edited"><Fa icon="pencil-alt"/></template>
+ <template v-if="message.is_edited"><i class="fas fa-pencil-alt"></i></template>
</footer>
</div>
</div>
@@ -221,7 +221,7 @@ export default defineComponent({
margin: 0 8px;
}
- > [data-icon] {
+ > i {
margin-left: 4px;
}
}
diff --git a/src/client/pages/messaging/messaging-room.vue b/src/client/pages/messaging/messaging-room.vue
index dae4590213..44bfd6c51d 100644
--- a/src/client/pages/messaging/messaging-room.vue
+++ b/src/client/pages/messaging/messaging-room.vue
@@ -6,10 +6,10 @@
<div class="_content mk-messaging-room">
<div class="body">
<MkLoading v-if="fetching"/>
- <p class="empty" v-if="!fetching && messages.length == 0"><Fa :icon="faInfoCircle"/>{{ $ts.noMessagesYet }}</p>
- <p class="no-history" v-if="!fetching && messages.length > 0 && !existMoreMessages"><Fa :icon="faFlag"/>{{ $ts.noMoreHistory }}</p>
+ <p class="empty" v-if="!fetching && messages.length == 0"><i class="fas fa-info-circle"></i>{{ $ts.noMessagesYet }}</p>
+ <p class="no-history" v-if="!fetching && messages.length > 0 && !existMoreMessages"><i class="fas fa-flag"></i>{{ $ts.noMoreHistory }}</p>
<button class="more _button" ref="loadMore" :class="{ fetching: fetchingMoreMessages }" v-show="existMoreMessages" @click="fetchMoreMessages" :disabled="fetchingMoreMessages">
- <template v-if="fetchingMoreMessages"><Fa icon="spinner" pulse fixed-width/></template>{{ fetchingMoreMessages ? $ts.loading : $ts.loadMore }}
+ <template v-if="fetchingMoreMessages"><i class="fas fa-spinner fa-pulse fa-fw"></i></template>{{ fetchingMoreMessages ? $ts.loading : $ts.loadMore }}
</button>
<XList class="messages" :items="messages" v-slot="{ item: message }" direction="up" reversed>
<XMessage :message="message" :is-group="group != null" :key="message.id"/>
@@ -26,7 +26,7 @@
</div>
<transition name="fade">
<div class="new-message" v-show="showIndicator">
- <button class="_buttonPrimary" @click="onIndicatorClick"><i><Fa :icon="faArrowCircleDown"/></i>{{ $ts.newMessageExists }}</button>
+ <button class="_buttonPrimary" @click="onIndicatorClick"><i class="fas fa-arrow-circle-down"></i>{{ $ts.newMessageExists }}</button>
</div>
</transition>
<XForm v-if="!fetching" :user="user" :group="group" ref="form"/>
@@ -37,8 +37,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faArrowCircleDown, faFlag, faUsers, faInfoCircle, faEllipsisH, faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons';
-import { faWindowMaximize } from '@fortawesome/free-regular-svg-icons';
import XList from '@client/components/date-separated-list.vue';
import XMessage from './messaging-room.message.vue';
import XForm from './messaging-room.form.vue';
@@ -75,14 +73,14 @@ const Component = defineComponent({
userName: this.user,
avatar: this.user,
action: {
- icon: faEllipsisH,
+ icon: 'fas fa-ellipsis-h',
handler: this.menu,
},
} : {
title: this.group.name,
- icon: faUsers,
+ icon: 'fas fa-users',
action: {
- icon: faEllipsisH,
+ icon: 'fas fa-ellipsis-h',
handler: this.menu,
},
} : null),
@@ -103,7 +101,6 @@ const Component = defineComponent({
&& this.existMoreMessages
&& this.fetchMoreMessages()
),
- faArrowCircleDown, faFlag, faInfoCircle
};
},
@@ -325,14 +322,14 @@ const Component = defineComponent({
os.modalMenu([this.inWindow ? undefined : {
text: this.$ts.openInWindow,
- icon: faWindowMaximize,
+ icon: 'fas fa-window-maximize',
action: () => {
os.pageWindow(path);
this.$router.back();
},
}, this.inWindow ? undefined : {
text: this.$ts.popout,
- icon: faExternalLinkAlt,
+ icon: 'fas fa-external-link-alt',
action: () => {
popout(path);
this.$router.back();
@@ -356,7 +353,7 @@ export default Component;
font-size: 0.8em;
opacity: 0.5;
- [data-icon] {
+ i {
margin-right: 4px;
}
}
@@ -370,7 +367,7 @@ export default Component;
color: var(--messagingRoomInfo);
opacity: 0.5;
- [data-icon] {
+ i {
margin-right: 4px;
}
}
@@ -396,7 +393,7 @@ export default Component;
cursor: wait;
}
- > [data-icon] {
+ > i {
margin-right: 4px;
}
}
diff --git a/src/client/pages/mfm-cheat-sheet.vue b/src/client/pages/mfm-cheat-sheet.vue
index 36f40dbcab..5227855236 100644
--- a/src/client/pages/mfm-cheat-sheet.vue
+++ b/src/client/pages/mfm-cheat-sheet.vue
@@ -266,7 +266,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faQuestionCircle } from '@fortawesome/free-regular-svg-icons';
import MkTextarea from '@client/components/ui/textarea.vue';
import * as symbols from '@client/symbols';
@@ -279,7 +278,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts._mfm.cheatSheet,
- icon: faQuestionCircle,
+ icon: 'fas fa-question-circle',
},
preview_mention: '@example',
preview_hashtag: '#test',
diff --git a/src/client/pages/my-antennas/index.antenna.vue b/src/client/pages/my-antennas/index.antenna.vue
index d7050d08c4..8cad6fa553 100644
--- a/src/client/pages/my-antennas/index.antenna.vue
+++ b/src/client/pages/my-antennas/index.antenna.vue
@@ -39,15 +39,14 @@
<MkSwitch v-model:value="notify">{{ $ts.notifyAntenna }}</MkSwitch>
</div>
<div class="_footer">
- <MkButton inline @click="saveAntenna()" primary><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- <MkButton inline @click="deleteAntenna()" v-if="antenna.id != null"><Fa :icon="faTrash"/> {{ $ts.delete }}</MkButton>
+ <MkButton inline @click="saveAntenna()" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
+ <MkButton inline @click="deleteAntenna()" v-if="antenna.id != null"><i class="fas fa-trash"></i> {{ $ts.delete }}</MkButton>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faSave, faTrash } from '@fortawesome/free-solid-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
import MkTextarea from '@client/components/ui/textarea.vue';
@@ -83,7 +82,6 @@ export default defineComponent({
notify: false,
userLists: null,
userGroups: null,
- faSave, faTrash
};
},
diff --git a/src/client/pages/my-antennas/index.vue b/src/client/pages/my-antennas/index.vue
index dfb752b831..57c55cefdd 100644
--- a/src/client/pages/my-antennas/index.vue
+++ b/src/client/pages/my-antennas/index.vue
@@ -1,6 +1,6 @@
<template>
<div class="ieepwinx _section">
- <MkButton @click="create" primary class="add"><Fa :icon="faPlus"/> {{ $ts.add }}</MkButton>
+ <MkButton @click="create" primary class="add"><i class="fas fa-plus"></i> {{ $ts.add }}</MkButton>
<div class="_content">
<XAntenna v-if="draft" :antenna="draft" @created="onAntennaCreated" style="margin-bottom: var(--margin);"/>
@@ -14,7 +14,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faSatellite, faPlus } from '@fortawesome/free-solid-svg-icons';
import MkPagination from '@client/components/ui/pagination.vue';
import MkButton from '@client/components/ui/button.vue';
import XAntenna from './index.antenna.vue';
@@ -31,9 +30,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.manageAntennas,
- icon: faSatellite,
+ icon: 'fas fa-satellite',
action: {
- icon: faPlus,
+ icon: 'fas fa-plus',
handler: this.create
}
},
@@ -42,7 +41,6 @@ export default defineComponent({
limit: 10,
},
draft: null,
- faSatellite, faPlus
};
},
diff --git a/src/client/pages/my-clips/index.vue b/src/client/pages/my-clips/index.vue
index 09cd7f828a..c4ca474748 100644
--- a/src/client/pages/my-clips/index.vue
+++ b/src/client/pages/my-clips/index.vue
@@ -1,6 +1,6 @@
<template>
<div class="_section qtcaoidl">
- <MkButton @click="create" primary class="add"><Fa :icon="faPlus"/> {{ $ts.add }}</MkButton>
+ <MkButton @click="create" primary class="add"><i class="fas fa-plus"></i> {{ $ts.add }}</MkButton>
<div class="_content">
<MkPagination :pagination="pagination" #default="{items}" ref="list" class="list">
@@ -15,7 +15,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPlus, faPaperclip } from '@fortawesome/free-solid-svg-icons';
import MkPagination from '@client/components/ui/pagination.vue';
import MkButton from '@client/components/ui/button.vue';
import * as os from '@client/os';
@@ -31,9 +30,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.clip,
- icon: faPaperclip,
+ icon: 'fas fa-paperclip',
action: {
- icon: faPlus,
+ icon: 'fas fa-plus',
handler: this.create
}
},
@@ -42,7 +41,6 @@ export default defineComponent({
limit: 10,
},
draft: null,
- faPlus
};
},
diff --git a/src/client/pages/my-groups/group.vue b/src/client/pages/my-groups/group.vue
index 90a60e5e2b..bd5537cbfa 100644
--- a/src/client/pages/my-groups/group.vue
+++ b/src/client/pages/my-groups/group.vue
@@ -23,7 +23,7 @@
<MkAcct :user="user" class="acct"/>
</div>
<div class="action">
- <button class="_button" @click="removeUser(user)"><Fa :icon="faTimes"/></button>
+ <button class="_button" @click="removeUser(user)"><i class="fas fa-times"></i></button>
</div>
</div>
</div>
@@ -35,7 +35,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faTimes, faUsers } from '@fortawesome/free-solid-svg-icons';
import Progress from '@client/scripts/loading';
import MkButton from '@client/components/ui/button.vue';
import * as os from '@client/os';
@@ -57,11 +56,10 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: computed(() => this.group ? {
title: this.group.name,
- icon: faUsers,
+ icon: 'fas fa-users',
} : null),
group: null,
users: [],
- faTimes, faUsers
};
},
diff --git a/src/client/pages/my-groups/index.vue b/src/client/pages/my-groups/index.vue
index 5125ce3f4f..9f153ff9cc 100644
--- a/src/client/pages/my-groups/index.vue
+++ b/src/client/pages/my-groups/index.vue
@@ -4,13 +4,13 @@
<MkTab v-model:value="tab">
<option value="owned">{{ $ts.ownedGroups }}</option>
<option value="joined">{{ $ts.joinedGroups }}</option>
- <option value="invites"><Fa :icon="faEnvelopeOpenText"/> {{ $ts.invites }}</option>
+ <option value="invites"><i class="fas fa-envelope-open-text"></i> {{ $ts.invites }}</option>
</MkTab>
</div>
<div class="_section">
<div class="_content" v-if="tab === 'owned'">
- <MkButton @click="create" primary style="margin: 0 auto var(--margin) auto;"><Fa :icon="faPlus"/> {{ $ts.createGroup }}</MkButton>
+ <MkButton @click="create" primary style="margin: 0 auto var(--margin) auto;"><i class="fas fa-plus"></i> {{ $ts.createGroup }}</MkButton>
<MkPagination :pagination="ownedPagination" #default="{items}" ref="owned">
<div class="_card" v-for="group in items" :key="group.id">
@@ -35,8 +35,8 @@
<div class="_title">{{ invitation.group.name }}</div>
<div class="_content"><MkAvatars :user-ids="invitation.group.userIds"/></div>
<div class="_footer">
- <MkButton @click="acceptInvite(invitation)" primary inline><Fa :icon="faCheck"/> {{ $ts.accept }}</MkButton>
- <MkButton @click="rejectInvite(invitation)" primary inline><Fa :icon="faBan"/> {{ $ts.reject }}</MkButton>
+ <MkButton @click="acceptInvite(invitation)" primary inline><i class="fas fa-check"></i> {{ $ts.accept }}</MkButton>
+ <MkButton @click="rejectInvite(invitation)" primary inline><i class="fas fa-ban"></i> {{ $ts.reject }}</MkButton>
</div>
</div>
</MkPagination>
@@ -47,7 +47,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faUsers, faPlus, faEnvelopeOpenText } from '@fortawesome/free-solid-svg-icons';
import MkPagination from '@client/components/ui/pagination.vue';
import MkButton from '@client/components/ui/button.vue';
import MkContainer from '@client/components/ui/container.vue';
@@ -69,7 +68,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.groups,
- icon: faUsers
+ icon: 'fas fa-users'
},
tab: 'owned',
ownedPagination: {
@@ -84,7 +83,6 @@ export default defineComponent({
endpoint: 'i/user-group-invites',
limit: 10,
},
- faUsers, faPlus, faEnvelopeOpenText
};
},
diff --git a/src/client/pages/my-lists/index.vue b/src/client/pages/my-lists/index.vue
index e680b90d1a..2b60917060 100644
--- a/src/client/pages/my-lists/index.vue
+++ b/src/client/pages/my-lists/index.vue
@@ -1,6 +1,6 @@
<template>
<div class="qkcjvfiv _section">
- <MkButton @click="create" primary class="add"><Fa :icon="faPlus"/> {{ $ts.createList }}</MkButton>
+ <MkButton @click="create" primary class="add"><i class="fas fa-plus"></i> {{ $ts.createList }}</MkButton>
<MkPagination :pagination="pagination" #default="{items}" class="lists _content" ref="list">
<div class="list _panel" v-for="(list, i) in items" :key="list.id">
@@ -12,7 +12,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faListUl, faPlus } from '@fortawesome/free-solid-svg-icons';
import MkPagination from '@client/components/ui/pagination.vue';
import MkButton from '@client/components/ui/button.vue';
import * as os from '@client/os';
@@ -28,9 +27,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.manageLists,
- icon: faListUl,
+ icon: 'fas fa-list-ul',
action: {
- icon: faPlus,
+ icon: 'fas fa-plus',
handler: this.create
}
},
@@ -38,7 +37,6 @@ export default defineComponent({
endpoint: 'users/lists/list',
limit: 10,
},
- faListUl, faPlus
};
},
diff --git a/src/client/pages/my-lists/list.vue b/src/client/pages/my-lists/list.vue
index 2892150ffe..049d370b4e 100644
--- a/src/client/pages/my-lists/list.vue
+++ b/src/client/pages/my-lists/list.vue
@@ -22,7 +22,7 @@
<MkAcct :user="user" class="acct"/>
</div>
<div class="action">
- <button class="_button" @click="removeUser(user)"><Fa :icon="faTimes"/></button>
+ <button class="_button" @click="removeUser(user)"><i class="fas fa-times"></i></button>
</div>
</div>
</div>
@@ -34,7 +34,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faTimes, faListUl } from '@fortawesome/free-solid-svg-icons';
import Progress from '@client/scripts/loading';
import MkButton from '@client/components/ui/button.vue';
import * as os from '@client/os';
@@ -49,11 +48,10 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: computed(() => this.list ? {
title: this.list.name,
- icon: faListUl,
+ icon: 'fas fa-list-ul',
} : null),
list: null,
users: [],
- faTimes, faListUl
};
},
diff --git a/src/client/pages/not-found.vue b/src/client/pages/not-found.vue
index b13bdac2b8..5e7fe17f75 100644
--- a/src/client/pages/not-found.vue
+++ b/src/client/pages/not-found.vue
@@ -9,7 +9,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import * as os from '@client/os';
import * as symbols from '@client/symbols';
@@ -18,7 +17,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.notFound,
- icon: faExclamationTriangle
+ icon: 'fas fa-exclamation-triangle'
},
}
},
diff --git a/src/client/pages/note.vue b/src/client/pages/note.vue
index 279dd96661..ce4af4eb4e 100644
--- a/src/client/pages/note.vue
+++ b/src/client/pages/note.vue
@@ -7,7 +7,7 @@
</div>
<div class="main _gap">
- <MkButton v-if="!showNext && hasNext" class="load next" @click="showNext = true"><Fa :icon="faChevronUp"/></MkButton>
+ <MkButton v-if="!showNext && hasNext" class="load next" @click="showNext = true"><i class="fas fa-chevron-up"></i></MkButton>
<div class="_content _gap">
<MkRemoteCaution v-if="note.user.host != null" :href="note.url || note.uri" class="_gap"/>
<XNoteDetailed v-model:note="note" :key="note.id" class="_gap"/>
@@ -22,7 +22,7 @@
</div>
</MkA>
</div>
- <MkButton v-if="!showPrev && hasPrev" class="load prev" @click="showPrev = true"><Fa :icon="faChevronDown"/></MkButton>
+ <MkButton v-if="!showPrev && hasPrev" class="load prev" @click="showPrev = true"><i class="fas fa-chevron-down"></i></MkButton>
</div>
<div class="_gap" v-if="showPrev">
@@ -37,7 +37,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faChevronUp, faChevronDown } from '@fortawesome/free-solid-svg-icons';
import XNote from '@client/components/note.vue';
import XNoteDetailed from '@client/components/note-detailed.vue';
import XNotes from '@client/components/notes.vue';
@@ -95,7 +94,6 @@ export default defineComponent({
sinceId: this.note.id,
})
},
- faChevronUp, faChevronDown
};
},
watch: {
diff --git a/src/client/pages/notifications.vue b/src/client/pages/notifications.vue
index 25605988ed..38797d746e 100644
--- a/src/client/pages/notifications.vue
+++ b/src/client/pages/notifications.vue
@@ -6,7 +6,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faBell, faCheck } from '@fortawesome/free-solid-svg-icons';
import Progress from '@client/scripts/loading';
import XNotifications from '@client/components/notifications.vue';
import * as os from '@client/os';
@@ -21,10 +20,10 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.notifications,
- icon: faBell,
+ icon: 'fas fa-bell',
actions: [{
text: this.$ts.markAllAsRead,
- icon: faCheck,
+ icon: 'fas fa-check',
handler: () => {
os.apiWithDialog('notifications/mark-all-as-read');
}
diff --git a/src/client/pages/page-editor/els/page-editor.el.button.vue b/src/client/pages/page-editor/els/page-editor.el.button.vue
index 1515187676..6e9036faac 100644
--- a/src/client/pages/page-editor/els/page-editor.el.button.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.button.vue
@@ -1,6 +1,6 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faBolt"/> {{ $ts._pages.blocks.button }}</template>
+ <template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.button }}</template>
<section class="xfhsjczc">
<MkInput v-model:value="value.text"><span>{{ $ts._pages.blocks._button.text }}</span></MkInput>
@@ -39,7 +39,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faBolt } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkSelect from '@client/components/ui/select.vue';
import MkInput from '@client/components/ui/input.vue';
@@ -62,7 +61,6 @@ export default defineComponent({
data() {
return {
- faBolt
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.canvas.vue b/src/client/pages/page-editor/els/page-editor.el.canvas.vue
index 9d4b4c76d2..59d29b9b71 100644
--- a/src/client/pages/page-editor/els/page-editor.el.canvas.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.canvas.vue
@@ -1,9 +1,9 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faPaintBrush"/> {{ $ts._pages.blocks.canvas }}</template>
+ <template #header><i class="fas fa-paint-brush"></i> {{ $ts._pages.blocks.canvas }}</template>
<section style="padding: 0 16px 0 16px;">
- <MkInput v-model:value="value.name"><template #prefix><Fa :icon="faMagic"/></template><span>{{ $ts._pages.blocks._canvas.id }}</span></MkInput>
+ <MkInput v-model:value="value.name"><template #prefix><i class="fas fa-magic"></i></template><span>{{ $ts._pages.blocks._canvas.id }}</span></MkInput>
<MkInput v-model:value="value.width" type="number"><span>{{ $ts._pages.blocks._canvas.width }}</span><template #suffix>px</template></MkInput>
<MkInput v-model:value="value.height" type="number"><span>{{ $ts._pages.blocks._canvas.height }}</span><template #suffix>px</template></MkInput>
</section>
@@ -12,7 +12,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPaintBrush, faMagic } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkInput from '@client/components/ui/input.vue';
import * as os from '@client/os';
@@ -30,7 +29,6 @@ export default defineComponent({
data() {
return {
- faPaintBrush, faMagic
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.counter.vue b/src/client/pages/page-editor/els/page-editor.el.counter.vue
index e16962aee9..3394817b53 100644
--- a/src/client/pages/page-editor/els/page-editor.el.counter.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.counter.vue
@@ -1,9 +1,9 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faBolt"/> {{ $ts._pages.blocks.counter }}</template>
+ <template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.counter }}</template>
<section style="padding: 0 16px 0 16px;">
- <MkInput v-model:value="value.name"><template #prefix><Fa :icon="faMagic"/></template><span>{{ $ts._pages.blocks._counter.name }}</span></MkInput>
+ <MkInput v-model:value="value.name"><template #prefix><i class="fas fa-magic"></i></template><span>{{ $ts._pages.blocks._counter.name }}</span></MkInput>
<MkInput v-model:value="value.text"><span>{{ $ts._pages.blocks._counter.text }}</span></MkInput>
<MkInput v-model:value="value.inc" type="number"><span>{{ $ts._pages.blocks._counter.inc }}</span></MkInput>
</section>
@@ -12,7 +12,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkInput from '@client/components/ui/input.vue';
import * as os from '@client/os';
@@ -30,7 +29,6 @@ export default defineComponent({
data() {
return {
- faBolt, faMagic
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.if.vue b/src/client/pages/page-editor/els/page-editor.el.if.vue
index 0cbfaa7eb8..7f4ed458aa 100644
--- a/src/client/pages/page-editor/els/page-editor.el.if.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.if.vue
@@ -1,9 +1,9 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faQuestion"/> {{ $ts._pages.blocks.if }}</template>
+ <template #header><i class="fas fa-question"></i> {{ $ts._pages.blocks.if }}</template>
<template #func>
<button @click="add()" class="_button">
- <Fa :icon="faPlus"/>
+ <i class="fas fa-plus"></i>
</button>
</template>
@@ -27,7 +27,6 @@
<script lang="ts">
import { defineComponent, defineAsyncComponent } from 'vue';
import { v4 as uuid } from 'uuid';
-import { faPlus, faQuestion } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkSelect from '@client/components/ui/select.vue';
import * as os from '@client/os';
@@ -51,7 +50,6 @@ export default defineComponent({
data() {
return {
- faPlus, faQuestion
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.image.vue b/src/client/pages/page-editor/els/page-editor.el.image.vue
index 1a96e42679..d96879f50d 100644
--- a/src/client/pages/page-editor/els/page-editor.el.image.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.image.vue
@@ -1,9 +1,9 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faImage"/> {{ $ts._pages.blocks.image }}</template>
+ <template #header><i class="fas fa-image"></i> {{ $ts._pages.blocks.image }}</template>
<template #func>
<button @click="choose()">
- <Fa :icon="faFolderOpen"/>
+ <i class="fas fa-folder-open"></i>
</button>
</template>
@@ -15,8 +15,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
-import { faImage, faFolderOpen } from '@fortawesome/free-regular-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkDriveFileThumbnail from '@client/components/drive-file-thumbnail.vue';
import * as os from '@client/os';
@@ -35,7 +33,6 @@ export default defineComponent({
data() {
return {
file: null,
- faPencilAlt, faImage, faFolderOpen
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.note.vue b/src/client/pages/page-editor/els/page-editor.el.note.vue
index 3f7eaf7572..d4801f3059 100644
--- a/src/client/pages/page-editor/els/page-editor.el.note.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.note.vue
@@ -1,6 +1,6 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faStickyNote"/> {{ $ts._pages.blocks.note }}</template>
+ <template #header><i class="fas fa-sticky-note"></i> {{ $ts._pages.blocks.note }}</template>
<section style="padding: 0 16px 0 16px;">
<MkInput v-model:value="id">
@@ -17,7 +17,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faStickyNote } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkInput from '@client/components/ui/input.vue';
import MkSwitch from '@client/components/ui/switch.vue';
@@ -40,7 +39,6 @@ export default defineComponent({
return {
id: this.value.note,
note: null,
- faStickyNote
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.number-input.vue b/src/client/pages/page-editor/els/page-editor.el.number-input.vue
index 76c35d4406..8058d941c1 100644
--- a/src/client/pages/page-editor/els/page-editor.el.number-input.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.number-input.vue
@@ -1,9 +1,9 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faBolt"/> {{ $ts._pages.blocks.numberInput }}</template>
+ <template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.numberInput }}</template>
<section style="padding: 0 16px 0 16px;">
- <MkInput v-model:value="value.name"><template #prefix><Fa :icon="faMagic"/></template><span>{{ $ts._pages.blocks._numberInput.name }}</span></MkInput>
+ <MkInput v-model:value="value.name"><template #prefix><i class="fas fa-magic"></i></template><span>{{ $ts._pages.blocks._numberInput.name }}</span></MkInput>
<MkInput v-model:value="value.text"><span>{{ $ts._pages.blocks._numberInput.text }}</span></MkInput>
<MkInput v-model:value="value.default" type="number"><span>{{ $ts._pages.blocks._numberInput.default }}</span></MkInput>
</section>
@@ -12,7 +12,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkInput from '@client/components/ui/input.vue';
import * as os from '@client/os';
@@ -30,7 +29,6 @@ export default defineComponent({
data() {
return {
- faBolt, faMagic
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.post.vue b/src/client/pages/page-editor/els/page-editor.el.post.vue
index 51c5481d54..1ed7f860c8 100644
--- a/src/client/pages/page-editor/els/page-editor.el.post.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.post.vue
@@ -1,6 +1,6 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faPaperPlane"/> {{ $ts._pages.blocks.post }}</template>
+ <template #header><i class="fas fa-paper-plane"></i> {{ $ts._pages.blocks.post }}</template>
<section style="padding: 16px;">
<MkTextarea v-model:value="value.text">{{ $ts._pages.blocks._post.text }}</MkTextarea>
@@ -12,7 +12,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPaperPlane } from '@fortawesome/free-regular-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkTextarea from '@client/components/ui/textarea.vue';
import MkInput from '@client/components/ui/input.vue';
@@ -32,7 +31,6 @@ export default defineComponent({
data() {
return {
- faPaperPlane
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.radio-button.vue b/src/client/pages/page-editor/els/page-editor.el.radio-button.vue
index 82b09a6290..97715ed69c 100644
--- a/src/client/pages/page-editor/els/page-editor.el.radio-button.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.radio-button.vue
@@ -1,9 +1,9 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faBolt"/> {{ $ts._pages.blocks.radioButton }}</template>
+ <template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.radioButton }}</template>
<section style="padding: 0 16px 16px 16px;">
- <MkInput v-model:value="value.name"><template #prefix><Fa :icon="faMagic"/></template><span>{{ $ts._pages.blocks._radioButton.name }}</span></MkInput>
+ <MkInput v-model:value="value.name"><template #prefix><i class="fas fa-magic"></i></template><span>{{ $ts._pages.blocks._radioButton.name }}</span></MkInput>
<MkInput v-model:value="value.title"><span>{{ $ts._pages.blocks._radioButton.title }}</span></MkInput>
<MkTextarea v-model:value="values"><span>{{ $ts._pages.blocks._radioButton.values }}</span></MkTextarea>
<MkInput v-model:value="value.default"><span>{{ $ts._pages.blocks._radioButton.default }}</span></MkInput>
@@ -13,7 +13,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkTextarea from '@client/components/ui/textarea.vue';
import MkInput from '@client/components/ui/input.vue';
@@ -31,7 +30,6 @@ export default defineComponent({
data() {
return {
values: '',
- faBolt, faMagic
};
},
watch: {
diff --git a/src/client/pages/page-editor/els/page-editor.el.section.vue b/src/client/pages/page-editor/els/page-editor.el.section.vue
index 96f468b13a..16ef2598f9 100644
--- a/src/client/pages/page-editor/els/page-editor.el.section.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.section.vue
@@ -1,12 +1,12 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faStickyNote"/> {{ value.title }}</template>
+ <template #header><i class="fas fa-sticky-note"></i> {{ value.title }}</template>
<template #func>
<button @click="rename()" class="_button">
- <Fa :icon="faPencilAlt"/>
+ <i class="fas fa-pencil-alt"></i>
</button>
<button @click="add()" class="_button">
- <Fa :icon="faPlus"/>
+ <i class="fas fa-plus"></i>
</button>
</template>
@@ -19,8 +19,6 @@
<script lang="ts">
import { defineComponent, defineAsyncComponent } from 'vue';
import { v4 as uuid } from 'uuid';
-import { faPlus, faPencilAlt } from '@fortawesome/free-solid-svg-icons';
-import { faStickyNote } from '@fortawesome/free-regular-svg-icons';
import XContainer from '../page-editor.container.vue';
import * as os from '@client/os';
@@ -43,7 +41,6 @@ export default defineComponent({
data() {
return {
- faStickyNote, faPlus, faPencilAlt
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.switch.vue b/src/client/pages/page-editor/els/page-editor.el.switch.vue
index 56b9f1561c..564d5e22c3 100644
--- a/src/client/pages/page-editor/els/page-editor.el.switch.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.switch.vue
@@ -1,9 +1,9 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faBolt"/> {{ $ts._pages.blocks.switch }}</template>
+ <template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.switch }}</template>
<section class="kjuadyyj">
- <MkInput v-model:value="value.name"><template #prefix><Fa :icon="faMagic"/></template><span>{{ $ts._pages.blocks._switch.name }}</span></MkInput>
+ <MkInput v-model:value="value.name"><template #prefix><i class="fas fa-magic"></i></template><span>{{ $ts._pages.blocks._switch.name }}</span></MkInput>
<MkInput v-model:value="value.text"><span>{{ $ts._pages.blocks._switch.text }}</span></MkInput>
<MkSwitch v-model:value="value.default"><span>{{ $ts._pages.blocks._switch.default }}</span></MkSwitch>
</section>
@@ -12,7 +12,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkSwitch from '@client/components/ui/switch.vue';
import MkInput from '@client/components/ui/input.vue';
@@ -31,7 +30,6 @@ export default defineComponent({
data() {
return {
- faBolt, faMagic
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.text-input.vue b/src/client/pages/page-editor/els/page-editor.el.text-input.vue
index cb8cb83aa7..4435d9b841 100644
--- a/src/client/pages/page-editor/els/page-editor.el.text-input.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.text-input.vue
@@ -1,9 +1,9 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faBolt"/> {{ $ts._pages.blocks.textInput }}</template>
+ <template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.textInput }}</template>
<section style="padding: 0 16px 0 16px;">
- <MkInput v-model:value="value.name"><template #prefix><Fa :icon="faMagic"/></template><span>{{ $ts._pages.blocks._textInput.name }}</span></MkInput>
+ <MkInput v-model:value="value.name"><template #prefix><i class="fas fa-magic"></i></template><span>{{ $ts._pages.blocks._textInput.name }}</span></MkInput>
<MkInput v-model:value="value.text"><span>{{ $ts._pages.blocks._textInput.text }}</span></MkInput>
<MkInput v-model:value="value.default" type="text"><span>{{ $ts._pages.blocks._textInput.default }}</span></MkInput>
</section>
@@ -12,7 +12,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkInput from '@client/components/ui/input.vue';
import * as os from '@client/os';
@@ -30,7 +29,6 @@ export default defineComponent({
data() {
return {
- faBolt, faMagic
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.text.vue b/src/client/pages/page-editor/els/page-editor.el.text.vue
index bd2c9c46dc..668dd5f52d 100644
--- a/src/client/pages/page-editor/els/page-editor.el.text.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.text.vue
@@ -1,6 +1,6 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faAlignLeft"/> {{ $ts._pages.blocks.text }}</template>
+ <template #header><i class="fas fa-align-left"></i> {{ $ts._pages.blocks.text }}</template>
<section class="vckmsadr">
<textarea v-model="value.text"></textarea>
@@ -10,7 +10,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faAlignLeft } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import * as os from '@client/os';
@@ -27,7 +26,6 @@ export default defineComponent({
data() {
return {
- faAlignLeft,
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.textarea-input.vue b/src/client/pages/page-editor/els/page-editor.el.textarea-input.vue
index 8c4ff23408..cf3b9f93f4 100644
--- a/src/client/pages/page-editor/els/page-editor.el.textarea-input.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.textarea-input.vue
@@ -1,9 +1,9 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faBolt"/> {{ $ts._pages.blocks.textareaInput }}</template>
+ <template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.textareaInput }}</template>
<section style="padding: 0 16px 16px 16px;">
- <MkInput v-model:value="value.name"><template #prefix><Fa :icon="faMagic"/></template><span>{{ $ts._pages.blocks._textareaInput.name }}</span></MkInput>
+ <MkInput v-model:value="value.name"><template #prefix><i class="fas fa-magic"></i></template><span>{{ $ts._pages.blocks._textareaInput.name }}</span></MkInput>
<MkInput v-model:value="value.text"><span>{{ $ts._pages.blocks._textareaInput.text }}</span></MkInput>
<MkTextarea v-model:value="value.default"><span>{{ $ts._pages.blocks._textareaInput.default }}</span></MkTextarea>
</section>
@@ -12,7 +12,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import MkTextarea from '@client/components/ui/textarea.vue';
import MkInput from '@client/components/ui/input.vue';
@@ -31,7 +30,6 @@ export default defineComponent({
data() {
return {
- faBolt, faMagic
};
},
diff --git a/src/client/pages/page-editor/els/page-editor.el.textarea.vue b/src/client/pages/page-editor/els/page-editor.el.textarea.vue
index 042b283731..a29d5bd3f2 100644
--- a/src/client/pages/page-editor/els/page-editor.el.textarea.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.textarea.vue
@@ -1,6 +1,6 @@
<template>
<XContainer @remove="() => $emit('remove')" :draggable="true">
- <template #header><Fa :icon="faAlignLeft"/> {{ $ts._pages.blocks.textarea }}</template>
+ <template #header><i class="fas fa-align-left"></i> {{ $ts._pages.blocks.textarea }}</template>
<section class="ihymsbbe">
<textarea v-model="value.text"></textarea>
@@ -10,7 +10,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faAlignLeft } from '@fortawesome/free-solid-svg-icons';
import XContainer from '../page-editor.container.vue';
import * as os from '@client/os';
@@ -27,7 +26,6 @@ export default defineComponent({
data() {
return {
- faAlignLeft,
};
},
diff --git a/src/client/pages/page-editor/page-editor.container.vue b/src/client/pages/page-editor/page-editor.container.vue
index 46e2dca157..afd261fac7 100644
--- a/src/client/pages/page-editor/page-editor.container.vue
+++ b/src/client/pages/page-editor/page-editor.container.vue
@@ -5,14 +5,14 @@
<div class="buttons">
<slot name="func"></slot>
<button v-if="removable" @click="remove()" class="_button">
- <Fa :icon="faTrashAlt"/>
+ <i class="fas fa-trash-alt"></i>
</button>
<button v-if="draggable" class="drag-handle _button">
- <Fa :icon="faBars"/>
+ <i class="fas fa-bars"></i>
</button>
<button @click="toggleContent(!showBody)" class="_button">
- <template v-if="showBody"><Fa :icon="faAngleUp"/></template>
- <template v-else><Fa :icon="faAngleDown"/></template>
+ <template v-if="showBody"><i class="fas fa-angle-up"></i></template>
+ <template v-else><i class="fas fa-angle-down"></i></template>
</button>
</div>
</header>
@@ -26,8 +26,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faBars, faAngleUp, faAngleDown } from '@fortawesome/free-solid-svg-icons';
-import { faTrashAlt } from '@fortawesome/free-regular-svg-icons';
export default defineComponent({
props: {
@@ -56,7 +54,6 @@ export default defineComponent({
data() {
return {
showBody: this.expanded,
- faTrashAlt, faBars, faAngleUp, faAngleDown
};
},
methods: {
@@ -105,7 +102,7 @@ export default defineComponent({
font-weight: bold;
box-shadow: 0 1px rgba(#000, 0.07);
- > [data-icon] {
+ > i {
margin-right: 6px;
}
diff --git a/src/client/pages/page-editor/page-editor.script-block.vue b/src/client/pages/page-editor/page-editor.script-block.vue
index 10d5311cde..65ac731e47 100644
--- a/src/client/pages/page-editor/page-editor.script-block.vue
+++ b/src/client/pages/page-editor/page-editor.script-block.vue
@@ -1,9 +1,9 @@
<template>
<XContainer :removable="removable" @remove="() => $emit('remove')" :error="error" :warn="warn" :draggable="draggable">
- <template #header><Fa v-if="icon" :icon="icon"/> <template v-if="title">{{ title }} <span class="turmquns" v-if="typeText">({{ typeText }})</span></template><template v-else-if="typeText">{{ typeText }}</template></template>
+ <template #header><i v-if="icon" :class="icon"></i> <template v-if="title">{{ title }} <span class="turmquns" v-if="typeText">({{ typeText }})</span></template><template v-else-if="typeText">{{ typeText }}</template></template>
<template #func>
<button @click="changeType()" class="_button">
- <Fa :icon="faPencilAlt"/>
+ <i class="fas fa-pencil-alt"></i>
</button>
</template>
@@ -57,7 +57,6 @@
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
-import { faPencilAlt, faPlug } from '@fortawesome/free-solid-svg-icons';
import { v4 as uuid } from 'uuid';
import XContainer from './page-editor.container.vue';
import MkTextarea from '@client/components/ui/textarea.vue';
@@ -109,14 +108,13 @@ export default defineComponent({
error: null,
warn: null,
slots: '',
- faPencilAlt
};
},
computed: {
icon(): any {
if (this.value.type === null) return null;
- if (this.value.type.startsWith('fn:')) return faPlug;
+ if (this.value.type.startsWith('fn:')) return 'fas fa-plug';
return blockDefs.find(x => x.type === this.value.type).icon;
},
typeText(): any {
diff --git a/src/client/pages/page-editor/page-editor.vue b/src/client/pages/page-editor/page-editor.vue
index 4583863a1c..e96e1faaf2 100644
--- a/src/client/pages/page-editor/page-editor.vue
+++ b/src/client/pages/page-editor/page-editor.vue
@@ -1,15 +1,15 @@
<template>
<div class="_root">
- <MkA class="view" v-if="pageId" :to="`/@${ author.username }/pages/${ currentName }`"><Fa :icon="faExternalLinkSquareAlt"/> {{ $ts._pages.viewPage }}</MkA>
+ <MkA class="view" v-if="pageId" :to="`/@${ author.username }/pages/${ currentName }`"><i class="fas fa-external-link-square-alt"></i> {{ $ts._pages.viewPage }}</MkA>
<div class="buttons" style="margin: 16px;">
- <MkButton inline @click="save" primary class="save" v-if="!readonly"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- <MkButton inline @click="duplicate" class="duplicate" v-if="pageId"><Fa :icon="faCopy"/> {{ $ts.duplicate }}</MkButton>
- <MkButton inline @click="del" class="delete" v-if="pageId && !readonly"><Fa :icon="faTrashAlt"/> {{ $ts.delete }}</MkButton>
+ <MkButton inline @click="save" primary class="save" v-if="!readonly"><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
+ <MkButton inline @click="duplicate" class="duplicate" v-if="pageId"><i class="fas fa-copy"></i> {{ $ts.duplicate }}</MkButton>
+ <MkButton inline @click="del" class="delete" v-if="pageId && !readonly"><i class="fas fa-trash-alt"></i> {{ $ts.delete }}</MkButton>
</div>
<MkContainer :foldable="true" :expanded="true" class="_gap">
- <template #header><Fa :icon="faCog"/> {{ $ts._pages.pageSetting }}</template>
+ <template #header><i class="fas fa-cog"></i> {{ $ts._pages.pageSetting }}</template>
<div style="padding: 16px;">
<MkInput v-model:value="title">
<span>{{ $ts._pages.title }}</span>
@@ -35,26 +35,26 @@
<MkSwitch v-model:value="hideTitleWhenPinned">{{ $ts._pages.hideTitleWhenPinned }}</MkSwitch>
<div class="eyeCatch">
- <MkButton v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage"><Fa :icon="faPlus"/> {{ $ts._pages.eyeCatchingImageSet }}</MkButton>
+ <MkButton v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage"><i class="fas fa-plus"></i> {{ $ts._pages.eyeCatchingImageSet }}</MkButton>
<div v-else-if="eyeCatchingImage">
<img :src="eyeCatchingImage.url" :alt="eyeCatchingImage.name" style="max-width: 100%;"/>
- <MkButton @click="removeEyeCatchingImage()" v-if="!readonly"><Fa :icon="faTrashAlt"/> {{ $ts._pages.eyeCatchingImageRemove }}</MkButton>
+ <MkButton @click="removeEyeCatchingImage()" v-if="!readonly"><i class="fas fa-trash-alt"></i> {{ $ts._pages.eyeCatchingImageRemove }}</MkButton>
</div>
</div>
</div>
</MkContainer>
<MkContainer :foldable="true" :expanded="true" class="_gap">
- <template #header><Fa :icon="faStickyNote"/> {{ $ts._pages.contents }}</template>
+ <template #header><i class="fas fa-sticky-note"></i> {{ $ts._pages.contents }}</template>
<div style="padding: 16px;">
<XBlocks class="content" v-model:value="content" :hpml="hpml"/>
- <MkButton @click="add()" v-if="!readonly"><Fa :icon="faPlus"/></MkButton>
+ <MkButton @click="add()" v-if="!readonly"><i class="fas fa-plus"></i></MkButton>
</div>
</MkContainer>
<MkContainer :foldable="true" class="_gap">
- <template #header><Fa :icon="faMagic"/> {{ $ts._pages.variables }}</template>
+ <template #header><i class="fas fa-magic"></i> {{ $ts._pages.variables }}</template>
<div class="qmuvgica">
<XDraggable tag="div" class="variables" v-show="variables.length > 0" v-model="variables" item-key="name" handle=".drag-handle" :group="{ name: 'variables' }" animation="150" swap-threshold="0.5">
<template #item="{element}">
@@ -70,12 +70,12 @@
</template>
</XDraggable>
- <MkButton @click="addVariable()" class="add" v-if="!readonly"><Fa :icon="faPlus"/></MkButton>
+ <MkButton @click="addVariable()" class="add" v-if="!readonly"><i class="fas fa-plus"></i></MkButton>
</div>
</MkContainer>
<MkContainer :foldable="true" :expanded="true" class="_gap">
- <template #header><Fa :icon="faCode"/> {{ $ts.script }}</template>
+ <template #header><i class="fas fa-code"></i> {{ $ts.script }}</template>
<div>
<MkTextarea class="_code" v-model:value="script"/>
</div>
@@ -91,8 +91,6 @@ import 'prismjs/components/prism-clike';
import 'prismjs/components/prism-javascript';
import 'prismjs/themes/prism-okaidia.css';
import 'vue-prism-editor/dist/prismeditor.min.css';
-import { faICursor, faPlus, faMagic, faCog, faCode, faExternalLinkSquareAlt, faPencilAlt, faCopy } from '@fortawesome/free-solid-svg-icons';
-import { faSave, faStickyNote, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import { v4 as uuid } from 'uuid';
import XVariable from './page-editor.script-block.vue';
import XBlocks from './page-editor.blocks.vue';
@@ -143,7 +141,7 @@ export default defineComponent({
}
return {
title: title,
- icon: faPencilAlt,
+ icon: 'fas fa-pencil-alt',
};
}),
author: this.$i,
@@ -164,7 +162,6 @@ export default defineComponent({
hpml: null,
script: '',
url,
- faPlus, faICursor, faSave, faStickyNote, faMagic, faCog, faTrashAlt, faExternalLinkSquareAlt, faCode, faCopy
};
},
@@ -471,7 +468,7 @@ export default defineComponent({
font-weight: bold;
box-shadow: 0 1px rgba(#000, 0.07);
- > [data-icon] {
+ > i {
margin-right: 6px;
}
diff --git a/src/client/pages/page.vue b/src/client/pages/page.vue
index d7b570e5f4..f25ed51184 100644
--- a/src/client/pages/page.vue
+++ b/src/client/pages/page.vue
@@ -14,8 +14,8 @@
<small style="display: block; opacity: 0.7; margin-top: 1em;">@{{ page.user.username }}</small>
</div>
<div class="like">
- <MkButton class="button" @click="unlike()" v-if="page.isLiked" v-tooltip="$ts._pages.unlike" primary><Fa :icon="faHeartS"/><span class="count" v-if="page.likedCount > 0">{{ page.likedCount }}</span></MkButton>
- <MkButton class="button" @click="like()" v-else v-tooltip="$ts._pages.like"><Fa :icon="faHeartR"/><span class="count" v-if="page.likedCount > 0">{{ page.likedCount }}</span></MkButton>
+ <MkButton class="button" @click="unlike()" v-if="page.isLiked" v-tooltip="$ts._pages.unlike" primary><i class="fas fa-heart"></i><span class="count" v-if="page.likedCount > 0">{{ page.likedCount }}</span></MkButton>
+ <MkButton class="button" @click="like()" v-else v-tooltip="$ts._pages.like"><i class="far fa-heart"></i><span class="count" v-if="page.likedCount > 0">{{ page.likedCount }}</span></MkButton>
</div>
<div class="links">
<MkA :to="`/@${username}/pages/${pageName}/view-source`" class="link">{{ $ts._pages.viewSource }}</MkA>
@@ -27,16 +27,14 @@
</div>
</div>
<div class="footer">
- <div><Fa :icon="faClock"/> {{ $ts.createdAt }}: <MkTime :time="page.createdAt" mode="detail"/></div>
- <div v-if="page.createdAt != page.updatedAt"><Fa :icon="faClock"/> {{ $ts.updatedAt }}: <MkTime :time="page.updatedAt" mode="detail"/></div>
+ <div><i class="far fa-clock"></i> {{ $ts.createdAt }}: <MkTime :time="page.createdAt" mode="detail"/></div>
+ <div v-if="page.createdAt != page.updatedAt"><i class="far fa-clock"></i> {{ $ts.updatedAt }}: <MkTime :time="page.updatedAt" mode="detail"/></div>
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faHeart as faHeartS } from '@fortawesome/free-solid-svg-icons';
-import { faHeart as faHeartR, faClock } from '@fortawesome/free-regular-svg-icons';
import XPage from '@client/components/page/page.vue';
import MkButton from '@client/components/ui/button.vue';
import * as os from '@client/os';
@@ -71,7 +69,6 @@ export default defineComponent({
},
} : null),
page: null,
- faHeartS, faHeartR, faClock,
};
},
diff --git a/src/client/pages/pages.vue b/src/client/pages/pages.vue
index 8aea7e6b95..52a860be13 100644
--- a/src/client/pages/pages.vue
+++ b/src/client/pages/pages.vue
@@ -1,9 +1,9 @@
<template>
<div>
<MkTab v-model:value="tab" v-if="$i">
- <option value="featured"><Fa :icon="faFireAlt"/> {{ $ts._pages.featured }}</option>
- <option value="my"><Fa :icon="faEdit"/> {{ $ts._pages.my }}</option>
- <option value="liked"><Fa :icon="faHeart"/> {{ $ts._pages.liked }}</option>
+ <option value="featured"><i class="fas fa-fire-alt"></i> {{ $ts._pages.featured }}</option>
+ <option value="my"><i class="fas fa-edit"></i> {{ $ts._pages.my }}</option>
+ <option value="liked"><i class="fas fa-heart"></i> {{ $ts._pages.liked }}</option>
</MkTab>
<div class="_section">
@@ -14,7 +14,7 @@
</div>
<div class="rknalgpo _content my" v-if="tab === 'my'">
- <MkButton class="new" @click="create()"><Fa :icon="faPlus"/></MkButton>
+ <MkButton class="new" @click="create()"><i class="fas fa-plus"></i></MkButton>
<MkPagination :pagination="myPagesPagination" #default="{items}">
<MkPagePreview v-for="page in items" class="ckltabjg" :page="page" :key="page.id"/>
</MkPagination>
@@ -31,8 +31,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPlus, faEdit, faFireAlt } from '@fortawesome/free-solid-svg-icons';
-import { faStickyNote, faHeart } from '@fortawesome/free-regular-svg-icons';
import MkPagePreview from '@client/components/page-preview.vue';
import MkPagination from '@client/components/ui/pagination.vue';
import MkButton from '@client/components/ui/button.vue';
@@ -47,9 +45,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.pages,
- icon: faStickyNote,
+ icon: 'fas fa-sticky-note',
actions: [{
- icon: faPlus,
+ icon: 'fas fa-plus',
text: this.$ts.create,
handler: this.create
}]
@@ -67,7 +65,6 @@ export default defineComponent({
endpoint: 'i/page-likes',
limit: 5,
},
- faStickyNote, faPlus, faEdit, faHeart, faFireAlt
};
},
methods: {
diff --git a/src/client/pages/preview.vue b/src/client/pages/preview.vue
index bd4e08db62..3df446e676 100644
--- a/src/client/pages/preview.vue
+++ b/src/client/pages/preview.vue
@@ -6,7 +6,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faEye } from '@fortawesome/free-solid-svg-icons';
import MkSample from '@client/components/sample.vue';
import * as symbols from '@client/symbols';
@@ -19,7 +18,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.preview,
- icon: faEye,
+ icon: 'fas fa-eye',
},
}
},
diff --git a/src/client/pages/reversi/game.board.vue b/src/client/pages/reversi/game.board.vue
index a466527c01..78bcf03413 100644
--- a/src/client/pages/reversi/game.board.vue
+++ b/src/client/pages/reversi/game.board.vue
@@ -40,8 +40,8 @@
<img v-if="stone === false" :src="whiteUser.avatarUrl" alt="white">
</template>
<template v-else>
- <fa v-if="stone === true" :icon="fasCircle"/>
- <fa v-if="stone === false" :icon="farCircle"/>
+ <i v-if="stone === true" class="fas fa-circle"></i>
+ <i v-if="stone === false" class="far fa-circle"></i>
</template>
</div>
</div>
@@ -63,12 +63,12 @@
<div class="player" v-if="game.isEnded">
<span>{{ logPos }} / {{ logs.length }}</span>
<div class="buttons" v-if="!autoplaying">
- <MkButton inline @click="logPos = 0" :disabled="logPos == 0"><fa :icon="faAngleDoubleLeft"/></MkButton>
- <MkButton inline @click="logPos--" :disabled="logPos == 0"><fa :icon="faAngleLeft"/></MkButton>
- <MkButton inline @click="logPos++" :disabled="logPos == logs.length"><fa :icon="faAngleRight"/></MkButton>
- <MkButton inline @click="logPos = logs.length" :disabled="logPos == logs.length"><fa :icon="faAngleDoubleRight"/></MkButton>
+ <MkButton inline @click="logPos = 0" :disabled="logPos == 0"><i class="fas fa-angle-double-left"></i></MkButton>
+ <MkButton inline @click="logPos--" :disabled="logPos == 0"><i class="fas fa-angle-left"></i></MkButton>
+ <MkButton inline @click="logPos++" :disabled="logPos == logs.length"><i class="fas fa-angle-right"></i></MkButton>
+ <MkButton inline @click="logPos = logs.length" :disabled="logPos == logs.length"><i class="fas fa-angle-double-right"></i></MkButton>
</div>
- <MkButton @click="autoplay()" :disabled="autoplaying" style="margin: var(--margin) auto 0 auto;"><fa :icon="faPlay"/></MkButton>
+ <MkButton @click="autoplay()" :disabled="autoplaying" style="margin: var(--margin) auto 0 auto;"><i class="fas fa-play"></i></MkButton>
</div>
<div class="info">
@@ -85,9 +85,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faAngleDoubleLeft, faAngleLeft, faAngleRight, faAngleDoubleRight, faPlay } from '@fortawesome/free-solid-svg-icons';
-import { faCircle as fasCircle } from '@fortawesome/free-solid-svg-icons';
-import { faCircle as farCircle } from '@fortawesome/free-regular-svg-icons';
import * as CRC32 from 'crc-32';
import Reversi, { Color } from '../../../games/reversi/core';
import { url } from '@client/config';
@@ -120,7 +117,6 @@ export default defineComponent({
logPos: 0,
watchers: [],
pollingClock: null,
- faAngleDoubleLeft, faAngleLeft, faAngleRight, faAngleDoubleRight, fasCircle, farCircle, faPlay
};
},
diff --git a/src/client/pages/reversi/game.setting.vue b/src/client/pages/reversi/game.setting.vue
index c7c2937ba8..1a2abba795 100644
--- a/src/client/pages/reversi/game.setting.vue
+++ b/src/client/pages/reversi/game.setting.vue
@@ -17,11 +17,11 @@
</header>
<div>
- <div class="random" v-if="game.map == null"><fa icon="dice"/></div>
+ <div class="random" v-if="game.map == null"><i class="fas fa-dice"></i></div>
<div class="board" v-else :style="{ 'grid-template-rows': `repeat(${ game.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.map[0].length }, 1fr)` }">
<div v-for="(x, i) in game.map.join('')" :class="{ none: x == ' ' }" @click="onPixelClick(i, x)">
- <fa v-if="x == 'b'" :icon="fasCircle"/>
- <fa v-if="x == 'w'" :icon="farCircle"/>
+ <i v-if="x === 'b'" class="fas fa-circle"></i>
+ <i v-if="x === 'w'" class="far fa-circle"></i>
</div>
</div>
</div>
@@ -125,8 +125,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faCircle as fasCircle } from '@fortawesome/free-solid-svg-icons';
-import { faCircle as farCircle } from '@fortawesome/free-regular-svg-icons';
import * as maps from '../../../games/reversi/maps';
import MkButton from '@client/components/ui/button.vue';
import MkSwitch from '@client/components/ui/switch.vue';
diff --git a/src/client/pages/reversi/game.vue b/src/client/pages/reversi/game.vue
index 896dbc39cc..62c99d7755 100644
--- a/src/client/pages/reversi/game.vue
+++ b/src/client/pages/reversi/game.vue
@@ -9,7 +9,6 @@ import { defineComponent } from 'vue';
import GameSetting from './game.setting.vue';
import GameBoard from './game.board.vue';
import * as os from '@client/os';
-import { faGamepad } from '@fortawesome/free-solid-svg-icons';
import * as symbols from '@client/symbols';
export default defineComponent({
@@ -29,7 +28,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts._reversi.reversi,
- icon: faGamepad
+ icon: 'fas fa-gamepad'
},
game: null,
connection: null,
diff --git a/src/client/pages/reversi/index.vue b/src/client/pages/reversi/index.vue
index 59b228f5f6..37126fca10 100644
--- a/src/client/pages/reversi/index.vue
+++ b/src/client/pages/reversi/index.vue
@@ -64,7 +64,6 @@ import { defineComponent } from 'vue';
import * as os from '@client/os';
import MkButton from '@client/components/ui/button.vue';
import MkFolder from '@client/components/ui/folder.vue';
-import { faGamepad } from '@fortawesome/free-solid-svg-icons';
import * as symbols from '@client/symbols';
export default defineComponent({
@@ -78,7 +77,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts._reversi.reversi,
- icon: faGamepad
+ icon: 'fas fa-gamepad'
},
games: [],
gamesFetching: true,
diff --git a/src/client/pages/room/room.vue b/src/client/pages/room/room.vue
index e1de52b8f1..ea34ef11b5 100644
--- a/src/client/pages/room/room.vue
+++ b/src/client/pages/room/room.vue
@@ -17,18 +17,18 @@
</template>
</div>
<div class="_content">
- <MkButton inline @click="translate()" :primary="isTranslateMode"><Fa :icon="faArrowsAlt"/> {{ $ts._rooms.translate }}</MkButton>
- <MkButton inline @click="rotate()" :primary="isRotateMode"><Fa :icon="faUndo"/> {{ $ts._rooms.rotate }}</MkButton>
- <MkButton inline v-if="isTranslateMode || isRotateMode" @click="exit()"><Fa :icon="faBan"/> {{ $ts._rooms.exit }}</MkButton>
+ <MkButton inline @click="translate()" :primary="isTranslateMode"><i class="fas fa-arrows-alt"></i> {{ $ts._rooms.translate }}</MkButton>
+ <MkButton inline @click="rotate()" :primary="isRotateMode"><i class="fas fa-undo"></i> {{ $ts._rooms.rotate }}</MkButton>
+ <MkButton inline v-if="isTranslateMode || isRotateMode" @click="exit()"><i class="fas fa-ban"></i> {{ $ts._rooms.exit }}</MkButton>
</div>
<div class="_content">
- <MkButton @click="remove()"><Fa :icon="faTrashAlt"/> {{ $ts._rooms.remove }}</MkButton>
+ <MkButton @click="remove()"><i class="fas fa-trash-alt"></i> {{ $ts._rooms.remove }}</MkButton>
</div>
</div>
<div class="menu _section" v-if="isMyRoom">
<div class="_content">
- <MkButton @click="add()"><Fa :icon="faBoxOpen"/> {{ $ts._rooms.addFurniture }}</MkButton>
+ <MkButton @click="add()"><i class="fas fa-box-open"></i> {{ $ts._rooms.addFurniture }}</MkButton>
</div>
<div class="_content">
<MkSelect :value="roomType" @update:value="updateRoomType($event)">
@@ -42,8 +42,8 @@
</label>
</div>
<div class="_content">
- <MkButton inline :disabled="!changed" primary @click="save()"><Fa :icon="faSave"/> {{ $ts.save }}</MkButton>
- <MkButton inline @click="clear()"><Fa :icon="faBroom"/> {{ $ts._rooms.clear }}</MkButton>
+ <MkButton inline :disabled="!changed" primary @click="save()"><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
+ <MkButton inline @click="clear()"><i class="fas fa-broom"></i> {{ $ts._rooms.clear }}</MkButton>
</div>
</div>
</div>
@@ -55,8 +55,6 @@ import { Room } from '@client/scripts/room/room';
import parseAcct from '@/misc/acct/parse';
import XPreview from './preview.vue';
const storeItems = require('@client/scripts/room/furnitures.json5');
-import { faBoxOpen, faUndo, faArrowsAlt, faBan, faBroom } from '@fortawesome/free-solid-svg-icons';
-import { faSave, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import { query as urlQuery } from '../../../prelude/url';
import MkButton from '@client/components/ui/button.vue';
import MkSelect from '@client/components/ui/select.vue';
@@ -98,7 +96,6 @@ export default defineComponent({
isRotateMode: false,
isMyRoom: false,
changed: false,
- faBoxOpen, faSave, faTrashAlt, faUndo, faArrowsAlt, faBan, faBroom,
};
},
diff --git a/src/client/pages/scratchpad.vue b/src/client/pages/scratchpad.vue
index 1a863e6b2e..99164ec51f 100644
--- a/src/client/pages/scratchpad.vue
+++ b/src/client/pages/scratchpad.vue
@@ -2,11 +2,11 @@
<div class="iltifgqe">
<div class="editor _panel _gap">
<PrismEditor class="_code code" v-model="code" :highlight="highlighter" :line-numbers="false"/>
- <MkButton style="position: absolute; top: 8px; right: 8px;" @click="run()" primary><Fa :icon="faPlay"/></MkButton>
+ <MkButton style="position: absolute; top: 8px; right: 8px;" @click="run()" primary><i class="fas fa-play"></i></MkButton>
</div>
<MkContainer :foldable="true" class="_gap">
- <template #header><Fa fixed-width/>{{ $ts.output }}</template>
+ <template #header>{{ $ts.output }}</template>
<div class="bepmlvbi">
<div v-for="log in logs" class="log" :key="log.id" :class="{ print: log.print }">{{ log.text }}</div>
</div>
@@ -20,7 +20,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faTerminal, faPlay } from '@fortawesome/free-solid-svg-icons';
import 'prismjs';
import { highlight, languages } from 'prismjs/components/prism-core';
import 'prismjs/components/prism-clike';
@@ -46,11 +45,10 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.scratchpad,
- icon: faTerminal,
+ icon: 'fas fa-terminal',
},
code: '',
logs: [],
- faTerminal, faPlay
}
},
diff --git a/src/client/pages/search.vue b/src/client/pages/search.vue
index b670714730..bf228576be 100644
--- a/src/client/pages/search.vue
+++ b/src/client/pages/search.vue
@@ -8,7 +8,6 @@
<script lang="ts">
import { computed, defineComponent } from 'vue';
-import { faSearch } from '@fortawesome/free-solid-svg-icons';
import Progress from '@client/scripts/loading';
import XNotes from '@client/components/notes.vue';
import * as symbols from '@client/symbols';
@@ -22,7 +21,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: computed(() => this.$t('searchWith', { q: this.$route.query.q })),
- icon: faSearch
+ icon: 'fas fa-search'
},
pagination: {
endpoint: 'notes/search',
diff --git a/src/client/pages/settings/2fa.vue b/src/client/pages/settings/2fa.vue
index 361611bcb2..aa14f91d71 100644
--- a/src/client/pages/settings/2fa.vue
+++ b/src/client/pages/settings/2fa.vue
@@ -1,6 +1,6 @@
<template>
<section class="_card">
- <div class="_title"><Fa :icon="faLock"/> {{ $ts.twoStepAuthentication }}</div>
+ <div class="_title"><i class="fas fa-lock"></i> {{ $ts.twoStepAuthentication }}</div>
<div class="_content">
<MkButton v-if="!data && !$i.twoFactorEnabled" @click="register">{{ $ts._2fa.registerDevice }}</MkButton>
<template v-if="$i.twoFactorEnabled">
@@ -28,7 +28,7 @@
<ol v-if="registration && !registration.error">
<li v-if="registration.stage >= 0">
{{ $ts.tapSecurityKey }}
- <Fa icon="spinner" pulse fixed-width v-if="registration.saving && registration.stage == 0" />
+ <i v-if="registration.saving && registration.stage == 0" class="fas fa-spinner fa-pulse fa-fw"></i>
</li>
<li v-if="registration.stage >= 1">
<MkForm :disabled="registration.stage != 1 || registration.saving">
@@ -36,7 +36,7 @@
<span>{{ $ts.securityKeyName }}</span>
</MkInput>
<MkButton @click="registerKey" :disabled="keyName.length == 0">{{ $ts.registerSecurityKey }}</MkButton>
- <Fa icon="spinner" pulse fixed-width v-if="registration.saving && registration.stage == 1" />
+ <i v-if="registration.saving && registration.stage == 1" class="fas fa-spinner fa-pulse fa-fw"></i>
</MkForm>
</li>
</ol>
@@ -68,7 +68,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faLock } from '@fortawesome/free-solid-svg-icons';
import { hostname } from '@client/config';
import { byteify, hexify, stringify } from '@client/scripts/2fa';
import MkButton from '@client/components/ui/button.vue';
@@ -93,7 +92,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.twoStepAuthentication,
- icon: faLock
+ icon: 'fas fa-lock'
},
data: null,
supportsCredentials: !!navigator.credentials,
@@ -101,7 +100,6 @@ export default defineComponent({
registration: null,
keyName: '',
token: null,
- faLock
};
},
diff --git a/src/client/pages/settings/account-info.vue b/src/client/pages/settings/account-info.vue
index 955a0f7845..4d851b7b12 100644
--- a/src/client/pages/settings/account-info.vue
+++ b/src/client/pages/settings/account-info.vue
@@ -132,7 +132,6 @@
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
-import { faInfoCircle } from '@fortawesome/free-solid-svg-icons';
import FormSwitch from '@client/components/form/switch.vue';
import FormSelect from '@client/components/form/select.vue';
import FormLink from '@client/components/form/link.vue';
@@ -162,7 +161,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.accountInfo,
- icon: faInfoCircle
+ icon: 'fas fa-info-circle'
},
stats: null
}
diff --git a/src/client/pages/settings/accounts.vue b/src/client/pages/settings/accounts.vue
new file mode 100644
index 0000000000..a3fa0d4eb0
--- /dev/null
+++ b/src/client/pages/settings/accounts.vue
@@ -0,0 +1,148 @@
+<template>
+<FormBase>
+ <FormSuspense :p="init">
+ <FormButton @click="addAccount" primary><i class="fas fa-plus"></i> {{ $ts.addAccount }}</FormButton>
+
+ <div class="_formItem _button" v-for="account in accounts" :key="account.id" @click="menu(account, $event)">
+ <div class="_formPanel lcjjdxlm">
+ <div class="avatar">
+ <MkAvatar :user="account" class="avatar"/>
+ </div>
+ <div class="body">
+ <div class="name">
+ <MkUserName :user="account"/>
+ </div>
+ <div class="acct">
+ <MkAcct :user="account"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </FormSuspense>
+</FormBase>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import FormSuspense from '@client/components/form/suspense.vue';
+import FormLink from '@client/components/form/link.vue';
+import FormBase from '@client/components/form/base.vue';
+import FormGroup from '@client/components/form/group.vue';
+import FormButton from '@client/components/form/button.vue';
+import * as os from '@client/os';
+import * as symbols from '@client/symbols';
+import { getAccounts, addAccount, login } from '@client/account';
+
+export default defineComponent({
+ components: {
+ FormBase,
+ FormSuspense,
+ FormButton,
+ },
+
+ emits: ['info'],
+
+ data() {
+ return {
+ [symbols.PAGE_INFO]: {
+ title: this.$ts.accounts,
+ icon: 'fas fa-users',
+ },
+ storedAccounts: getAccounts().filter(x => x.id !== this.$i.id),
+ accounts: null,
+ init: () => os.api('users/show', {
+ userIds: this.storedAccounts.map(x => x.id)
+ }).then(accounts => {
+ this.accounts = accounts;
+ }),
+ };
+ },
+
+ mounted() {
+ this.$emit('info', this[symbols.PAGE_INFO]);
+ },
+
+ methods: {
+ menu(account, ev) {
+ os.modalMenu([{
+ text: this.$ts.switch,
+ icon: 'fas fa-exchange-alt',
+ action: () => this.switchAccount(account),
+ }, {
+ text: this.$ts.remove,
+ icon: 'fas fa-trash-alt',
+ danger: true,
+ action: () => this.removeAccount(account),
+ }], ev.currentTarget || ev.target);
+ },
+
+ addAccount(ev) {
+ os.modalMenu([{
+ text: this.$ts.existingAccount,
+ action: () => { this.addExistingAccount(); },
+ }, {
+ text: this.$ts.createAccount,
+ action: () => { this.createAccount(); },
+ }], ev.currentTarget || ev.target);
+ },
+
+ addExistingAccount() {
+ os.popup(import('@client/components/signin-dialog.vue'), {}, {
+ done: res => {
+ addAccount(res.id, res.i);
+ os.success();
+ },
+ }, 'closed');
+ },
+
+ createAccount() {
+ os.popup(import('@client/components/signup-dialog.vue'), {}, {
+ done: res => {
+ addAccount(res.id, res.i);
+ this.switchAccountWithToken(res.i);
+ },
+ }, 'closed');
+ },
+
+ switchAccount(account: any) {
+ const storedAccounts = getAccounts();
+ const token = storedAccounts.find(x => x.id === account.id).token;
+ this.switchAccountWithToken(token);
+ },
+
+ switchAccountWithToken(token: string) {
+ login(token);
+ },
+ }
+});
+</script>
+
+<style lang="scss" scoped>
+.lcjjdxlm {
+ display: flex;
+ padding: 16px;
+
+ > .avatar {
+ display: block;
+ flex-shrink: 0;
+ margin: 0 12px 0 0;
+
+ > .avatar {
+ width: 50px;
+ height: 50px;
+ }
+ }
+
+ > .body {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ width: calc(100% - 62px);
+ position: relative;
+
+ > .name {
+ font-weight: bold;
+ }
+ }
+}
+</style>
diff --git a/src/client/pages/settings/api.vue b/src/client/pages/settings/api.vue
index 9b53399870..396d4405c3 100644
--- a/src/client/pages/settings/api.vue
+++ b/src/client/pages/settings/api.vue
@@ -8,7 +8,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faKey } from '@fortawesome/free-solid-svg-icons';
import FormSwitch from '@client/components/form/switch.vue';
import FormSelect from '@client/components/form/select.vue';
import FormLink from '@client/components/form/link.vue';
@@ -31,7 +30,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: 'API',
- icon: faKey
+ icon: 'fas fa-key'
},
isDesktop: window.innerWidth >= 1100,
};
diff --git a/src/client/pages/settings/apps.vue b/src/client/pages/settings/apps.vue
index 82bf9b7f8f..c864920ce1 100644
--- a/src/client/pages/settings/apps.vue
+++ b/src/client/pages/settings/apps.vue
@@ -22,7 +22,7 @@
<div><MkTime :time="token.lastUsedAt"/></div>
</div>
<div class="actions">
- <button class="_button" @click="revoke(token)"><Fa :icon="faTrashAlt"/></button>
+ <button class="_button" @click="revoke(token)"><i class="fas fa-trash-alt"></i></button>
</div>
<details>
<summary>{{ $ts.details }}</summary>
@@ -39,7 +39,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faTrashAlt, faPlug } from '@fortawesome/free-solid-svg-icons';
import FormPagination from '@client/components/form/pagination.vue';
import FormSelect from '@client/components/form/select.vue';
import FormLink from '@client/components/form/link.vue';
@@ -61,7 +60,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.installedApps,
- icon: faPlug,
+ icon: 'fas fa-plug',
},
pagination: {
endpoint: 'i/apps',
@@ -70,7 +69,6 @@ export default defineComponent({
sort: '+lastUsedAt'
}
},
- faTrashAlt, faPlug
};
},
diff --git a/src/client/pages/settings/deck.vue b/src/client/pages/settings/deck.vue
index 84992adc09..05f3061ca1 100644
--- a/src/client/pages/settings/deck.vue
+++ b/src/client/pages/settings/deck.vue
@@ -31,7 +31,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faImage, faCog, faColumns } from '@fortawesome/free-solid-svg-icons';
import FormSwitch from '@client/components/form/switch.vue';
import FormLink from '@client/components/form/link.vue';
import FormRadios from '@client/components/form/radios.vue';
@@ -59,9 +58,8 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.deck,
- icon: faColumns
+ icon: 'fas fa-columns'
},
- faImage, faCog,
}
},
diff --git a/src/client/pages/settings/drive.vue b/src/client/pages/settings/drive.vue
index 675b025ab8..3da2a21dc7 100644
--- a/src/client/pages/settings/drive.vue
+++ b/src/client/pages/settings/drive.vue
@@ -27,7 +27,7 @@
<FormButton :center="false" @click="chooseUploadFolder()" primary>
{{ $ts.uploadFolder }}
<template #suffix>{{ uploadFolder ? uploadFolder.name : '-' }}</template>
- <template #suffixIcon><Fa :icon="faFolderOpen"/></template>
+ <template #suffixIcon><i class="fas fa-folder-open"></i></template>
</FormButton>
</FormBase>
</template>
@@ -36,8 +36,6 @@
import { defineComponent } from 'vue';
import * as tinycolor from 'tinycolor2';
import ApexCharts from 'apexcharts';
-import { faCloud, faFolderOpen } from '@fortawesome/free-solid-svg-icons';
-import { faClock, faEyeSlash, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import FormButton from '@client/components/form/button.vue';
import FormGroup from '@client/components/form/group.vue';
import FormKeyValueView from '@client/components/form/key-value-view.vue';
@@ -60,13 +58,12 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.drive,
- icon: faCloud
+ icon: 'fas fa-cloud'
},
fetching: true,
usage: null,
capacity: null,
uploadFolder: null,
- faCloud, faClock, faEyeSlash, faFolderOpen, faTrashAlt
}
},
diff --git a/src/client/pages/settings/email-address.vue b/src/client/pages/settings/email-address.vue
index 97c5d396ce..28eeeb6b73 100644
--- a/src/client/pages/settings/email-address.vue
+++ b/src/client/pages/settings/email-address.vue
@@ -13,8 +13,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faCog } from '@fortawesome/free-solid-svg-icons';
-import { faBell, faEnvelope } from '@fortawesome/free-regular-svg-icons';
import FormButton from '@client/components/form/button.vue';
import FormInput from '@client/components/form/input.vue';
import FormBase from '@client/components/form/base.vue';
@@ -36,11 +34,10 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.emailAddress,
- icon: faEnvelope
+ icon: 'fas fa-envelope'
},
emailAddress: null,
code: null,
- faCog
}
},
diff --git a/src/client/pages/settings/email-notification.vue b/src/client/pages/settings/email-notification.vue
index cc28bac4b0..ac3402568a 100644
--- a/src/client/pages/settings/email-notification.vue
+++ b/src/client/pages/settings/email-notification.vue
@@ -25,8 +25,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faCog } from '@fortawesome/free-solid-svg-icons';
-import { faBell, faEnvelope } from '@fortawesome/free-regular-svg-icons';
import FormButton from '@client/components/form/button.vue';
import FormSwitch from '@client/components/form/switch.vue';
import FormBase from '@client/components/form/base.vue';
@@ -49,7 +47,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.emailNotification,
- icon: faEnvelope
+ icon: 'fas fa-envelope'
},
mention: this.$i.emailNotificationTypes.includes('mention'),
diff --git a/src/client/pages/settings/email.vue b/src/client/pages/settings/email.vue
index 04f433f9ae..aa20d9d94e 100644
--- a/src/client/pages/settings/email.vue
+++ b/src/client/pages/settings/email.vue
@@ -3,14 +3,14 @@
<FormGroup>
<template #label>{{ $ts.emailAddress }}</template>
<FormLink to="/settings/email/address">
- <template v-if="$i.email && !$i.emailVerified" #icon><Fa :icon="faExclamationTriangle" style="color: var(--warn);"/></template>
- <template v-else-if="$i.email && $i.emailVerified" #icon><Fa :icon="faCheck" style="color: var(--success);"/></template>
+ <template v-if="$i.email && !$i.emailVerified" #icon><i class="fas fa-exclamation-triangle" style="color: var(--warn);"></i></template>
+ <template v-else-if="$i.email && $i.emailVerified" #icon><i class="fas fa-check" style="color: var(--success);"></i></template>
{{ $i.email || $ts.notSet }}
</FormLink>
</FormGroup>
<FormLink to="/settings/email/notification">
- <template #icon><Fa :icon="faBell"/></template>
+ <template #icon><i class="fas fa-bell"></i></template>
{{ $ts.emailNotification }}
</FormLink>
@@ -22,8 +22,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faCog, faExclamationTriangle, faCheck } from '@fortawesome/free-solid-svg-icons';
-import { faBell, faEnvelope } from '@fortawesome/free-regular-svg-icons';
import FormButton from '@client/components/form/button.vue';
import FormLink from '@client/components/form/link.vue';
import FormBase from '@client/components/form/base.vue';
@@ -47,9 +45,8 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.email,
- icon: faEnvelope
+ icon: 'fas fa-envelope'
},
- faCog, faExclamationTriangle, faCheck, faBell
}
},
diff --git a/src/client/pages/settings/experimental-features.vue b/src/client/pages/settings/experimental-features.vue
index 25453b7e10..f8d5e419e9 100644
--- a/src/client/pages/settings/experimental-features.vue
+++ b/src/client/pages/settings/experimental-features.vue
@@ -6,7 +6,6 @@
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
-import { faFlask } from '@fortawesome/free-solid-svg-icons';
import FormSwitch from '@client/components/form/switch.vue';
import FormSelect from '@client/components/form/select.vue';
import FormLink from '@client/components/form/link.vue';
@@ -34,7 +33,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.experimentalFeatures,
- icon: faFlask
+ icon: 'fas fa-flask'
},
stats: null
}
diff --git a/src/client/pages/settings/general.vue b/src/client/pages/settings/general.vue
index 2963ddf432..fdbae0b8a1 100644
--- a/src/client/pages/settings/general.vue
+++ b/src/client/pages/settings/general.vue
@@ -83,7 +83,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faImage, faCog, faColumns, faCogs } from '@fortawesome/free-solid-svg-icons';
import FormSwitch from '@client/components/form/switch.vue';
import FormSelect from '@client/components/form/select.vue';
import FormRadios from '@client/components/form/radios.vue';
@@ -117,13 +116,12 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.general,
- icon: faCogs
+ icon: 'fas fa-cogs'
},
langs,
lang: localStorage.getItem('lang'),
fontSize: localStorage.getItem('fontSize'),
useSystemFont: localStorage.getItem('useSystemFont') != null,
- faImage, faCog, faColumns
}
},
diff --git a/src/client/pages/settings/import-export.vue b/src/client/pages/settings/import-export.vue
index 1591a9d548..e77efb4429 100644
--- a/src/client/pages/settings/import-export.vue
+++ b/src/client/pages/settings/import-export.vue
@@ -2,32 +2,31 @@
<FormBase>
<FormGroup>
<template #label>{{ $ts._exportOrImport.allNotes }}</template>
- <FormButton @click="doExport('notes')"><Fa :icon="faDownload"/> {{ $ts.export }}</FormButton>
+ <FormButton @click="doExport('notes')"><i class="fas fa-download"></i> {{ $ts.export }}</FormButton>
</FormGroup>
<FormGroup>
<template #label>{{ $ts._exportOrImport.followingList }}</template>
- <FormButton @click="doExport('following')"><Fa :icon="faDownload"/> {{ $ts.export }}</FormButton>
- <FormButton @click="doImport('following', $event)"><Fa :icon="faUpload"/> {{ $ts.import }}</FormButton>
+ <FormButton @click="doExport('following')"><i class="fas fa-download"></i> {{ $ts.export }}</FormButton>
+ <FormButton @click="doImport('following', $event)"><i class="fas fa-upload"></i> {{ $ts.import }}</FormButton>
</FormGroup>
<FormGroup>
<template #label>{{ $ts._exportOrImport.userLists }}</template>
- <FormButton @click="doExport('user-lists')"><Fa :icon="faDownload"/> {{ $ts.export }}</FormButton>
- <FormButton @click="doImport('user-lists', $event)"><Fa :icon="faUpload"/> {{ $ts.import }}</FormButton>
+ <FormButton @click="doExport('user-lists')"><i class="fas fa-download"></i> {{ $ts.export }}</FormButton>
+ <FormButton @click="doImport('user-lists', $event)"><i class="fas fa-upload"></i> {{ $ts.import }}</FormButton>
</FormGroup>
<FormGroup>
<template #label>{{ $ts._exportOrImport.muteList }}</template>
- <FormButton @click="doExport('mute')"><Fa :icon="faDownload"/> {{ $ts.export }}</FormButton>
+ <FormButton @click="doExport('mute')"><i class="fas fa-download"></i> {{ $ts.export }}</FormButton>
</FormGroup>
<FormGroup>
<template #label>{{ $ts._exportOrImport.blockingList }}</template>
- <FormButton @click="doExport('blocking')"><Fa :icon="faDownload"/> {{ $ts.export }}</FormButton>
+ <FormButton @click="doExport('blocking')"><i class="fas fa-download"></i> {{ $ts.export }}</FormButton>
</FormGroup>
</FormBase>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faDownload, faUpload, faBoxes } from '@fortawesome/free-solid-svg-icons';
import FormSelect from '@client/components/form/select.vue';
import FormButton from '@client/components/form/button.vue';
import FormBase from '@client/components/form/base.vue';
@@ -49,9 +48,8 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.importAndExport,
- icon: faBoxes
+ icon: 'fas fa-boxes'
},
- faDownload, faUpload, faBoxes
}
},
diff --git a/src/client/pages/settings/index.vue b/src/client/pages/settings/index.vue
index eb7469c861..049e912898 100644
--- a/src/client/pages/settings/index.vue
+++ b/src/client/pages/settings/index.vue
@@ -3,31 +3,39 @@
<div class="nav" v-if="!narrow || page == null">
<FormBase>
<FormGroup>
+ <div class="_formItem">
+ <div class="_formPanel lwjxoukj">
+ <MkAvatar :user="$i" class="avatar"/>
+ </div>
+ </div>
+ <FormLink :active="page === 'accounts'" replace to="/settings/accounts"><template #icon><i class="fas fa-users"></i></template>{{ $ts.accounts }}</FormLink>
+ </FormGroup>
+ <FormGroup>
<template #label>{{ $ts.basicSettings }}</template>
- <FormLink :active="page === 'profile'" replace to="/settings/profile"><template #icon><Fa :icon="faUser"/></template>{{ $ts.profile }}</FormLink>
- <FormLink :active="page === 'privacy'" replace to="/settings/privacy"><template #icon><Fa :icon="faLockOpen"/></template>{{ $ts.privacy }}</FormLink>
- <FormLink :active="page === 'reaction'" replace to="/settings/reaction"><template #icon><Fa :icon="faLaugh"/></template>{{ $ts.reaction }}</FormLink>
- <FormLink :active="page === 'drive'" replace to="/settings/drive"><template #icon><Fa :icon="faCloud"/></template>{{ $ts.drive }}</FormLink>
- <FormLink :active="page === 'notifications'" replace to="/settings/notifications"><template #icon><Fa :icon="faBell"/></template>{{ $ts.notifications }}</FormLink>
- <FormLink :active="page === 'email'" replace to="/settings/email"><template #icon><Fa :icon="faEnvelope"/></template>{{ $ts.email }}</FormLink>
- <FormLink :active="page === 'integration'" replace to="/settings/integration"><template #icon><Fa :icon="faShareAlt"/></template>{{ $ts.integration }}</FormLink>
- <FormLink :active="page === 'security'" replace to="/settings/security"><template #icon><Fa :icon="faLock"/></template>{{ $ts.security }}</FormLink>
+ <FormLink :active="page === 'profile'" replace to="/settings/profile"><template #icon><i class="fas fa-user"></i></template>{{ $ts.profile }}</FormLink>
+ <FormLink :active="page === 'privacy'" replace to="/settings/privacy"><template #icon><i class="fas fa-lock-open"></i></template>{{ $ts.privacy }}</FormLink>
+ <FormLink :active="page === 'reaction'" replace to="/settings/reaction"><template #icon><i class="fas fa-laugh"></i></template>{{ $ts.reaction }}</FormLink>
+ <FormLink :active="page === 'drive'" replace to="/settings/drive"><template #icon><i class="fas fa-cloud"></i></template>{{ $ts.drive }}</FormLink>
+ <FormLink :active="page === 'notifications'" replace to="/settings/notifications"><template #icon><i class="fas fa-bell"></i></template>{{ $ts.notifications }}</FormLink>
+ <FormLink :active="page === 'email'" replace to="/settings/email"><template #icon><i class="fas fa-envelope"></i></template>{{ $ts.email }}</FormLink>
+ <FormLink :active="page === 'integration'" replace to="/settings/integration"><template #icon><i class="fas fa-share-alt"></i></template>{{ $ts.integration }}</FormLink>
+ <FormLink :active="page === 'security'" replace to="/settings/security"><template #icon><i class="fas fa-lock"></i></template>{{ $ts.security }}</FormLink>
</FormGroup>
<FormGroup>
<template #label>{{ $ts.clientSettings }}</template>
- <FormLink :active="page === 'general'" replace to="/settings/general"><template #icon><Fa :icon="faCogs"/></template>{{ $ts.general }}</FormLink>
- <FormLink :active="page === 'theme'" replace to="/settings/theme"><template #icon><Fa :icon="faPalette"/></template>{{ $ts.theme }}</FormLink>
- <FormLink :active="page === 'sidebar'" replace to="/settings/sidebar"><template #icon><Fa :icon="faListUl"/></template>{{ $ts.sidebar }}</FormLink>
- <FormLink :active="page === 'sounds'" replace to="/settings/sounds"><template #icon><Fa :icon="faMusic"/></template>{{ $ts.sounds }}</FormLink>
- <FormLink :active="page === 'plugin'" replace to="/settings/plugin"><template #icon><Fa :icon="faPlug"/></template>{{ $ts.plugins }}</FormLink>
+ <FormLink :active="page === 'general'" replace to="/settings/general"><template #icon><i class="fas fa-cogs"></i></template>{{ $ts.general }}</FormLink>
+ <FormLink :active="page === 'theme'" replace to="/settings/theme"><template #icon><i class="fas fa-palette"></i></template>{{ $ts.theme }}</FormLink>
+ <FormLink :active="page === 'sidebar'" replace to="/settings/sidebar"><template #icon><i class="fas fa-list-ul"></i></template>{{ $ts.sidebar }}</FormLink>
+ <FormLink :active="page === 'sounds'" replace to="/settings/sounds"><template #icon><i class="fas fa-music"></i></template>{{ $ts.sounds }}</FormLink>
+ <FormLink :active="page === 'plugin'" replace to="/settings/plugin"><template #icon><i class="fas fa-plug"></i></template>{{ $ts.plugins }}</FormLink>
</FormGroup>
<FormGroup>
<template #label>{{ $ts.otherSettings }}</template>
- <FormLink :active="page === 'import-export'" replace to="/settings/import-export"><template #icon><Fa :icon="faBoxes"/></template>{{ $ts.importAndExport }}</FormLink>
- <FormLink :active="page === 'mute-block'" replace to="/settings/mute-block"><template #icon><Fa :icon="faBan"/></template>{{ $ts.muteAndBlock }}</FormLink>
- <FormLink :active="page === 'word-mute'" replace to="/settings/word-mute"><template #icon><Fa :icon="faCommentSlash"/></template>{{ $ts.wordMute }}</FormLink>
- <FormLink :active="page === 'api'" replace to="/settings/api"><template #icon><Fa :icon="faKey"/></template>API</FormLink>
- <FormLink :active="page === 'other'" replace to="/settings/other"><template #icon><Fa :icon="faEllipsisH"/></template>{{ $ts.other }}</FormLink>
+ <FormLink :active="page === 'import-export'" replace to="/settings/import-export"><template #icon><i class="fas fa-boxes"></i></template>{{ $ts.importAndExport }}</FormLink>
+ <FormLink :active="page === 'mute-block'" replace to="/settings/mute-block"><template #icon><i class="fas fa-ban"></i></template>{{ $ts.muteAndBlock }}</FormLink>
+ <FormLink :active="page === 'word-mute'" replace to="/settings/word-mute"><template #icon><i class="fas fa-comment-slash"></i></template>{{ $ts.wordMute }}</FormLink>
+ <FormLink :active="page === 'api'" replace to="/settings/api"><template #icon><i class="fas fa-key"></i></template>API</FormLink>
+ <FormLink :active="page === 'other'" replace to="/settings/other"><template #icon><i class="fas fa-ellipsis-h"></i></template>{{ $ts.other }}</FormLink>
</FormGroup>
<FormGroup>
<FormButton @click="clear">{{ $ts.clearCache }}</FormButton>
@@ -45,8 +53,6 @@
<script lang="ts">
import { computed, defineAsyncComponent, defineComponent, nextTick, onMounted, reactive, ref, watch } from 'vue';
-import { faCog, faPalette, faPlug, faUser, faListUl, faLock, faCommentSlash, faMusic, faCogs, faEllipsisH, faBan, faShareAlt, faLockOpen, faKey, faBoxes, faCloud } from '@fortawesome/free-solid-svg-icons';
-import { faLaugh, faBell, faEnvelope } from '@fortawesome/free-regular-svg-icons';
import { i18n } from '@client/i18n';
import FormLink from '@client/components/form/link.vue';
import FormGroup from '@client/components/form/group.vue';
@@ -75,7 +81,7 @@ export default defineComponent({
setup(props, context) {
const indexInfo = {
title: i18n.locale.settings,
- icon: faCog
+ icon: 'fas fa-cog'
};
const INFO = ref(indexInfo);
const page = ref(props.initialPage);
@@ -89,6 +95,7 @@ export default defineComponent({
const component = computed(() => {
if (page.value == null) return null;
switch (page.value) {
+ case 'accounts': return defineAsyncComponent(() => import('./accounts.vue'));
case 'profile': return defineAsyncComponent(() => import('./profile.vue'));
case 'privacy': return defineAsyncComponent(() => import('./privacy.vue'));
case 'reaction': return defineAsyncComponent(() => import('./reaction.vue'));
@@ -183,7 +190,6 @@ export default defineComponent({
localStorage.removeItem('theme');
unisonReload();
},
- faPalette, faPlug, faUser, faListUl, faLock, faLaugh, faCommentSlash, faMusic, faBell, faCogs, faEllipsisH, faBan, faShareAlt, faLockOpen, faKey, faBoxes, faEnvelope, faCloud,
};
},
});
@@ -212,4 +218,15 @@ export default defineComponent({
}
}
}
+
+.lwjxoukj {
+ padding: 16px;
+
+ > .avatar {
+ display: block;
+ margin: auto;
+ width: 42px;
+ height: 42px;
+ }
+}
</style>
diff --git a/src/client/pages/settings/integration.vue b/src/client/pages/settings/integration.vue
index 49f955bc35..2d2be04051 100644
--- a/src/client/pages/settings/integration.vue
+++ b/src/client/pages/settings/integration.vue
@@ -1,7 +1,7 @@
<template>
<FormBase>
<div class="_formItem" v-if="enableTwitterIntegration">
- <div class="_formLabel"><Fa :icon="faTwitter"/> Twitter</div>
+ <div class="_formLabel"><i class="fab fa-twitter"></i> Twitter</div>
<div class="_formPanel" style="padding: 16px;">
<p v-if="integrations.twitter">{{ $ts.connectedTo }}: <a :href="`https://twitter.com/${integrations.twitter.screenName}`" rel="nofollow noopener" target="_blank">@{{ integrations.twitter.screenName }}</a></p>
<MkButton v-if="integrations.twitter" @click="disconnectTwitter" danger>{{ $ts.disconnectSerice }}</MkButton>
@@ -10,7 +10,7 @@
</div>
<div class="_formItem" v-if="enableDiscordIntegration">
- <div class="_formLabel"><Fa :icon="faDiscord"/> Discord</div>
+ <div class="_formLabel"><i class="fab fa-discord"></i> Discord</div>
<div class="_formPanel" style="padding: 16px;">
<p v-if="integrations.discord">{{ $ts.connectedTo }}: <a :href="`https://discord.com/users/${integrations.discord.id}`" rel="nofollow noopener" target="_blank">@{{ integrations.discord.username }}#{{ integrations.discord.discriminator }}</a></p>
<MkButton v-if="integrations.discord" @click="disconnectDiscord" danger>{{ $ts.disconnectSerice }}</MkButton>
@@ -19,7 +19,7 @@
</div>
<div class="_formItem" v-if="enableGithubIntegration">
- <div class="_formLabel"><Fa :icon="faGithub"/> GitHub</div>
+ <div class="_formLabel"><i class="fab fa-github"></i> GitHub</div>
<div class="_formPanel" style="padding: 16px;">
<p v-if="integrations.github">{{ $ts.connectedTo }}: <a :href="`https://github.com/${integrations.github.login}`" rel="nofollow noopener" target="_blank">@{{ integrations.github.login }}</a></p>
<MkButton v-if="integrations.github" @click="disconnectGithub" danger>{{ $ts.disconnectSerice }}</MkButton>
@@ -31,8 +31,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faShareAlt } from '@fortawesome/free-solid-svg-icons';
-import { faTwitter, faDiscord, faGithub } from '@fortawesome/free-brands-svg-icons';
import { apiUrl } from '@client/config';
import FormBase from '@client/components/form/base.vue';
import MkButton from '@client/components/ui/button.vue';
@@ -51,7 +49,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.integration,
- icon: faShareAlt
+ icon: 'fas fa-share-alt'
},
apiUrl,
twitterForm: null,
@@ -60,7 +58,6 @@ export default defineComponent({
enableTwitterIntegration: false,
enableDiscordIntegration: false,
enableGithubIntegration: false,
- faShareAlt, faTwitter, faDiscord, faGithub
};
},
diff --git a/src/client/pages/settings/mute-block.vue b/src/client/pages/settings/mute-block.vue
index 11450e049b..dde0199e18 100644
--- a/src/client/pages/settings/mute-block.vue
+++ b/src/client/pages/settings/mute-block.vue
@@ -33,7 +33,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faBan } from '@fortawesome/free-solid-svg-icons';
import MkPagination from '@client/components/ui/pagination.vue';
import MkTab from '@client/components/tab.vue';
import FormInfo from '@client/components/form/info.vue';
@@ -60,7 +59,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.muteAndBlock,
- icon: faBan
+ icon: 'fas fa-ban'
},
tab: 'mute',
mutingPagination: {
diff --git a/src/client/pages/settings/notifications.vue b/src/client/pages/settings/notifications.vue
index ea72bcfee8..ec95452ba2 100644
--- a/src/client/pages/settings/notifications.vue
+++ b/src/client/pages/settings/notifications.vue
@@ -11,8 +11,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faCog } from '@fortawesome/free-solid-svg-icons';
-import { faBell } from '@fortawesome/free-regular-svg-icons';
import FormButton from '@client/components/form/button.vue';
import FormLink from '@client/components/form/link.vue';
import FormBase from '@client/components/form/base.vue';
@@ -35,9 +33,8 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.notifications,
- icon: faBell
+ icon: 'fas fa-bell'
},
- faCog
}
},
diff --git a/src/client/pages/settings/other.vue b/src/client/pages/settings/other.vue
index 2bd9c2476c..f73ff9cb21 100644
--- a/src/client/pages/settings/other.vue
+++ b/src/client/pages/settings/other.vue
@@ -21,10 +21,10 @@
</template>
</FormGroup>
- <FormLink to="/settings/registry"><template #icon><Fa :icon="faCogs"/></template>{{ $ts.registry }}</FormLink>
+ <FormLink to="/settings/registry"><template #icon><i class="fas fa-cogs"></i></template>{{ $ts.registry }}</FormLink>
- <FormLink to="/bios" behavior="browser"><template #icon><Fa :icon="faDoorOpen"/></template>BIOS</FormLink>
- <FormLink to="/cli" behavior="browser"><template #icon><Fa :icon="faDoorOpen"/></template>CLI</FormLink>
+ <FormLink to="/bios" behavior="browser"><template #icon><i class="fas fa-door-open"></i></template>BIOS</FormLink>
+ <FormLink to="/cli" behavior="browser"><template #icon><i class="fas fa-door-open"></i></template>CLI</FormLink>
<FormButton @click="closeAccount" danger>{{ $ts.closeAccount }}</FormButton>
</FormBase>
@@ -32,7 +32,6 @@
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
-import { faEllipsisH, faCogs, faDoorOpen } from '@fortawesome/free-solid-svg-icons';
import FormSwitch from '@client/components/form/switch.vue';
import FormSelect from '@client/components/form/select.vue';
import FormLink from '@client/components/form/link.vue';
@@ -62,10 +61,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.other,
- icon: faEllipsisH
+ icon: 'fas fa-ellipsis-h'
},
debug,
- faCogs, faDoorOpen,
}
},
diff --git a/src/client/pages/settings/plugin.install.vue b/src/client/pages/settings/plugin.install.vue
index bc80188fc6..30cbf58ad7 100644
--- a/src/client/pages/settings/plugin.install.vue
+++ b/src/client/pages/settings/plugin.install.vue
@@ -8,13 +8,12 @@
</FormTextarea>
</FormGroup>
- <FormButton @click="install" :disabled="code == null" primary inline><Fa :icon="faCheck"/> {{ $ts.install }}</FormButton>
+ <FormButton @click="install" :disabled="code == null" primary inline><i class="fas fa-check"></i> {{ $ts.install }}</FormButton>
</FormBase>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye } from '@fortawesome/free-solid-svg-icons';
import { AiScript, parse } from '@syuilo/aiscript';
import { serialize } from '@syuilo/aiscript/built/serializer';
import { v4 as uuid } from 'uuid';
@@ -49,10 +48,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts._plugin.install,
- icon: faDownload
+ icon: 'fas fa-download'
},
code: null,
- faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye
}
},
diff --git a/src/client/pages/settings/plugin.manage.vue b/src/client/pages/settings/plugin.manage.vue
index d7aabe560e..3df87ca084 100644
--- a/src/client/pages/settings/plugin.manage.vue
+++ b/src/client/pages/settings/plugin.manage.vue
@@ -22,8 +22,8 @@
</div>
<div class="_formItem">
<div class="_formPanel" style="padding: 16px;">
- <MkButton @click="config(plugin)" inline v-if="plugin.config"><Fa :icon="faCog"/> {{ $ts.settings }}</MkButton>
- <MkButton @click="uninstall(plugin)" inline danger><Fa :icon="faTrashAlt"/> {{ $ts.uninstall }}</MkButton>
+ <MkButton @click="config(plugin)" inline v-if="plugin.config"><i class="fas fa-cog"></i> {{ $ts.settings }}</MkButton>
+ <MkButton @click="uninstall(plugin)" inline danger><i class="fas fa-trash-alt"></i> {{ $ts.uninstall }}</MkButton>
</div>
</div>
</FormGroup>
@@ -32,7 +32,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPlug, faSave, faTrashAlt, faFolderOpen, faDownload, faCog } from '@fortawesome/free-solid-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import MkTextarea from '@client/components/ui/textarea.vue';
import MkSelect from '@client/components/ui/select.vue';
@@ -59,10 +58,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts._plugin.manage,
- icon: faPlug
+ icon: 'fas fa-plug'
},
plugins: ColdDeviceStorage.get('plugins'),
- faPlug, faSave, faTrashAlt, faFolderOpen, faDownload, faCog
}
},
diff --git a/src/client/pages/settings/plugin.vue b/src/client/pages/settings/plugin.vue
index bee4e57ec3..13eaca07fd 100644
--- a/src/client/pages/settings/plugin.vue
+++ b/src/client/pages/settings/plugin.vue
@@ -1,13 +1,12 @@
<template>
<FormBase>
- <FormLink to="/settings/plugin/install"><template #icon><Fa :icon="faDownload"/></template>{{ $ts._plugin.install }}</FormLink>
- <FormLink to="/settings/plugin/manage"><template #icon><Fa :icon="faFolderOpen"/></template>{{ $ts._plugin.manage }}<template #suffix>{{ plugins }}</template></FormLink>
+ <FormLink to="/settings/plugin/install"><template #icon><i class="fas fa-download"></i></template>{{ $ts._plugin.install }}</FormLink>
+ <FormLink to="/settings/plugin/manage"><template #icon><i class="fas fa-folder-open"></i></template>{{ $ts._plugin.manage }}<template #suffix>{{ plugins }}</template></FormLink>
</FormBase>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPlug, faSave, faTrashAlt, faFolderOpen, faDownload, faCog } from '@fortawesome/free-solid-svg-icons';
import FormBase from '@client/components/form/base.vue';
import FormGroup from '@client/components/form/group.vue';
import FormLink from '@client/components/form/link.vue';
@@ -27,10 +26,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.plugins,
- icon: faPlug
+ icon: 'fas fa-plug'
},
plugins: ColdDeviceStorage.get('plugins').length,
- faPlug, faSave, faTrashAlt, faFolderOpen, faDownload, faCog
}
},
diff --git a/src/client/pages/settings/privacy.vue b/src/client/pages/settings/privacy.vue
index c8df378410..4095e744c2 100644
--- a/src/client/pages/settings/privacy.vue
+++ b/src/client/pages/settings/privacy.vue
@@ -33,7 +33,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faLockOpen } from '@fortawesome/free-solid-svg-icons';
import FormSwitch from '@client/components/form/switch.vue';
import FormSelect from '@client/components/form/select.vue';
import FormBase from '@client/components/form/base.vue';
@@ -56,7 +55,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.privacy,
- icon: faLockOpen
+ icon: 'fas fa-lock-open'
},
isLocked: false,
autoAcceptFollowed: false,
diff --git a/src/client/pages/settings/profile.vue b/src/client/pages/settings/profile.vue
index 5ec580a206..de7e86bd12 100644
--- a/src/client/pages/settings/profile.vue
+++ b/src/client/pages/settings/profile.vue
@@ -19,12 +19,12 @@
<FormInput v-model:value="location" manual-save>
<span>{{ $ts.location }}</span>
- <template #prefix><Fa :icon="faMapMarkerAlt"/></template>
+ <template #prefix><i class="fas fa-map-marker-alt"></i></template>
</FormInput>
<FormInput v-model:value="birthday" type="date" manual-save>
<span>{{ $ts.birthday }}</span>
- <template #prefix><Fa :icon="faBirthdayCake"/></template>
+ <template #prefix><i class="fas fa-birthday-cake"></i></template>
</FormInput>
<FormSelect v-model:value="lang">
@@ -47,8 +47,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faUnlockAlt, faCogs, faUser, faMapMarkerAlt, faBirthdayCake } from '@fortawesome/free-solid-svg-icons';
-import { faSave } from '@fortawesome/free-regular-svg-icons';
import FormButton from '@client/components/form/button.vue';
import FormInput from '@client/components/form/input.vue';
import FormTextarea from '@client/components/form/textarea.vue';
@@ -78,7 +76,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.profile,
- icon: faUser
+ icon: 'fas fa-user'
},
host,
langs,
@@ -101,7 +99,6 @@ export default defineComponent({
isCat: false,
alwaysMarkNsfw: false,
saving: false,
- faSave, faUnlockAlt, faCogs, faUser, faMapMarkerAlt, faBirthdayCake
}
},
diff --git a/src/client/pages/settings/reaction.vue b/src/client/pages/settings/reaction.vue
index 0293f53fa8..9bffd5f903 100644
--- a/src/client/pages/settings/reaction.vue
+++ b/src/client/pages/settings/reaction.vue
@@ -10,7 +10,7 @@
</button>
</template>
<template #footer>
- <button class="_button add" @click="chooseEmoji"><Fa :icon="faPlus"/></button>
+ <button class="_button add" @click="chooseEmoji"><i class="fas fa-plus"></i></button>
</template>
</XDraggable>
</div>
@@ -29,15 +29,13 @@
<option :value="2">{{ $ts.medium }}</option>
<option :value="3">{{ $ts.large }}</option>
</FormRadios>
- <FormButton @click="preview"><Fa :icon="faEye"/> {{ $ts.preview }}</FormButton>
- <FormButton danger @click="setDefault"><Fa :icon="faUndo"/> {{ $ts.default }}</FormButton>
+ <FormButton @click="preview"><i class="fas fa-eye"></i> {{ $ts.preview }}</FormButton>
+ <FormButton danger @click="setDefault"><i class="fas fa-undo"></i> {{ $ts.default }}</FormButton>
</FormBase>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faLaugh, faSave, faEye } from '@fortawesome/free-regular-svg-icons';
-import { faUndo, faPlus } from '@fortawesome/free-solid-svg-icons';
import XDraggable from 'vuedraggable';
import FormInput from '@client/components/form/input.vue';
import FormRadios from '@client/components/form/radios.vue';
@@ -62,14 +60,13 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.reaction,
- icon: faLaugh,
+ icon: 'fas fa-laugh',
action: {
- icon: faEye,
+ icon: 'fas fa-eye',
handler: this.preview
}
},
reactions: JSON.parse(JSON.stringify(this.$store.state.reactions)),
- faLaugh, faSave, faEye, faUndo, faPlus
}
},
diff --git a/src/client/pages/settings/registry.keys.vue b/src/client/pages/settings/registry.keys.vue
index 5cdfdc1332..f71589ba4f 100644
--- a/src/client/pages/settings/registry.keys.vue
+++ b/src/client/pages/settings/registry.keys.vue
@@ -22,7 +22,6 @@
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
-import { faCogs } from '@fortawesome/free-solid-svg-icons';
import * as JSON5 from 'json5';
import FormSwitch from '@client/components/form/switch.vue';
import FormSelect from '@client/components/form/select.vue';
@@ -57,7 +56,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.registry,
- icon: faCogs
+ icon: 'fas fa-cogs'
},
keys: null,
}
diff --git a/src/client/pages/settings/registry.value.vue b/src/client/pages/settings/registry.value.vue
index 7d5756af99..48245ae99f 100644
--- a/src/client/pages/settings/registry.value.vue
+++ b/src/client/pages/settings/registry.value.vue
@@ -22,7 +22,7 @@
<FormTextarea tall v-model:value="valueForEditor" class="_monospace" style="tab-size: 2;">
<span>{{ $ts.value }} (JSON)</span>
</FormTextarea>
- <FormButton @click="save" primary><Fa :icon="faSave"/> {{ $ts.save }}</FormButton>
+ <FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
</FormGroup>
<FormKeyValueView>
@@ -30,14 +30,13 @@
<template #value><MkTime :time="value.updatedAt" mode="detail"/></template>
</FormKeyValueView>
- <FormButton danger @click="del"><Fa :icon="faTrash"/> {{ $ts.delete }}</FormButton>
+ <FormButton danger @click="del"><i class="fas fa-trash"></i> {{ $ts.delete }}</FormButton>
</template>
</FormBase>
</template>
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
-import { faCogs, faSave, faTrash } from '@fortawesome/free-solid-svg-icons';
import * as JSON5 from 'json5';
import FormInfo from '@client/components/form/info.vue';
import FormSwitch from '@client/components/form/switch.vue';
@@ -77,11 +76,10 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.registry,
- icon: faCogs
+ icon: 'fas fa-cogs'
},
value: null,
valueForEditor: null,
- faSave, faTrash,
}
},
diff --git a/src/client/pages/settings/registry.vue b/src/client/pages/settings/registry.vue
index 085389fc95..5ba1bc751b 100644
--- a/src/client/pages/settings/registry.vue
+++ b/src/client/pages/settings/registry.vue
@@ -10,7 +10,6 @@
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
-import { faCogs } from '@fortawesome/free-solid-svg-icons';
import * as JSON5 from 'json5';
import FormSwitch from '@client/components/form/switch.vue';
import FormSelect from '@client/components/form/select.vue';
@@ -39,7 +38,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.registry,
- icon: faCogs
+ icon: 'fas fa-cogs'
},
scopes: null,
}
diff --git a/src/client/pages/settings/security.vue b/src/client/pages/settings/security.vue
index 64733c55a2..b70fa5a9f3 100644
--- a/src/client/pages/settings/security.vue
+++ b/src/client/pages/settings/security.vue
@@ -1,15 +1,15 @@
<template>
<FormBase>
<X2fa/>
- <FormLink to="/settings/2fa"><template #icon><Fa :icon="faMobileAlt"/></template>{{ $ts.twoStepAuthentication }}</FormLink>
+ <FormLink to="/settings/2fa"><template #icon><i class="fas fa-mobile-alt"></i></template>{{ $ts.twoStepAuthentication }}</FormLink>
<FormButton primary @click="change()">{{ $ts.changePassword }}</FormButton>
<FormPagination :pagination="pagination">
<template #label>{{ $ts.signinHistory }}</template>
<template #default="{items}">
<div class="_formPanel timnmucd" v-for="item in items" :key="item.id">
<header>
- <Fa class="icon succ" :icon="faCheck" v-if="item.success"/>
- <Fa class="icon fail" :icon="faTimesCircle" v-else/>
+ <i v-if="item.success" class="fas fa-check icon succ"></i>
+ <i v-else class="fas fa-times-circle icon fail"></i>
<code class="ip _monospace">{{ item.ip }}</code>
<MkTime :time="item.createdAt" class="time"/>
</header>
@@ -17,7 +17,7 @@
</template>
</FormPagination>
<FormGroup>
- <FormButton danger @click="regenerateToken"><Fa :icon="faSyncAlt"/> {{ $ts.regenerateLoginToken }}</FormButton>
+ <FormButton danger @click="regenerateToken"><i class="fas fa-sync-alt"></i> {{ $ts.regenerateLoginToken }}</FormButton>
<template #caption>{{ $ts.regenerateLoginTokenDescription }}</template>
</FormGroup>
</FormBase>
@@ -25,7 +25,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faCheck, faTimesCircle, faLock, faSyncAlt, faMobileAlt } from '@fortawesome/free-solid-svg-icons';
import FormBase from '@client/components/form/base.vue';
import FormLink from '@client/components/form/link.vue';
import FormGroup from '@client/components/form/group.vue';
@@ -49,13 +48,12 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.security,
- icon: faLock
+ icon: 'fas fa-lock'
},
pagination: {
endpoint: 'i/signin-history',
limit: 5,
},
- faLock, faSyncAlt, faCheck, faTimesCircle, faMobileAlt,
}
},
diff --git a/src/client/pages/settings/sidebar.vue b/src/client/pages/settings/sidebar.vue
index adeec2f636..f0172e945f 100644
--- a/src/client/pages/settings/sidebar.vue
+++ b/src/client/pages/settings/sidebar.vue
@@ -12,14 +12,13 @@
<!-- <MkRadio v-model="sidebarDisplay" value="hide" disabled>{{ $ts._sidebar.hide }}</MkRadio>--> <!-- TODO: サイドバーを完全に隠せるようにすると、別途ハンバーガーボタンのようなものをUIに表示する必要があり面倒 -->
</FormRadios>
- <FormButton @click="save()" primary><Fa :icon="faSave"/> {{ $ts.save }}</FormButton>
- <FormButton @click="reset()" danger><Fa :icon="faRedo"/> {{ $ts.default }}</FormButton>
+ <FormButton @click="save()" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+ <FormButton @click="reset()" danger><i class="fas fa-redo"></i> {{ $ts.default }}</FormButton>
</FormBase>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faListUl, faSave, faRedo } from '@fortawesome/free-solid-svg-icons';
import FormSwitch from '@client/components/form/switch.vue';
import FormTextarea from '@client/components/form/textarea.vue';
import FormRadios from '@client/components/form/radios.vue';
@@ -45,11 +44,10 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.sidebar,
- icon: faListUl
+ icon: 'fas fa-list-ul'
},
menuDef: sidebarDef,
items: '',
- faSave, faRedo
}
},
diff --git a/src/client/pages/settings/sounds.vue b/src/client/pages/settings/sounds.vue
index 54be003115..f56ec4cd89 100644
--- a/src/client/pages/settings/sounds.vue
+++ b/src/client/pages/settings/sounds.vue
@@ -1,7 +1,7 @@
<template>
<FormBase>
<FormRange v-model:value="masterVolume" :min="0" :max="1" :step="0.05">
- <template #label><Fa :icon="volumeIcon" :key="volumeIcon"/> {{ $ts.masterVolume }}</template>
+ <template #label><i class="fas fa-volume-icon"></i> {{ $ts.masterVolume }}</template>
</FormRange>
<FormGroup>
@@ -9,17 +9,16 @@
<FormButton v-for="type in Object.keys(sounds)" :key="type" :center="false" @click="edit(type)">
{{ $t('_sfx.' + type) }}
<template #suffix>{{ sounds[type].type || $ts.none }}</template>
- <template #suffixIcon><Fa :icon="faChevronDown"/></template>
+ <template #suffixIcon><i class="fas fa-chevron-down"></i></template>
</FormButton>
</FormGroup>
- <FormButton @click="reset()" danger><Fa :icon="faRedo"/> {{ $ts.default }}</FormButton>
+ <FormButton @click="reset()" danger><i class="fas fa-redo"></i> {{ $ts.default }}</FormButton>
</FormBase>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faMusic, faPlay, faVolumeUp, faVolumeMute, faChevronDown, faRedo } from '@fortawesome/free-solid-svg-icons';
import FormRange from '@client/components/form/range.vue';
import FormSelect from '@client/components/form/select.vue';
import FormBase from '@client/components/form/base.vue';
@@ -71,10 +70,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.sounds,
- icon: faMusic
+ icon: 'fas fa-music'
},
sounds: {},
- faMusic, faPlay, faVolumeUp, faVolumeMute, faChevronDown, faRedo,
}
},
@@ -84,7 +82,7 @@ export default defineComponent({
set(value) { ColdDeviceStorage.set('sound_masterVolume', value); }
},
volumeIcon() {
- return this.masterVolume === 0 ? faVolumeMute : faVolumeUp;
+ return this.masterVolume === 0 ? 'fas fa-volume-mute' : 'fas fa-volume-up';
}
},
diff --git a/src/client/pages/settings/theme.install.vue b/src/client/pages/settings/theme.install.vue
index 744d1aba44..d719cc801f 100644
--- a/src/client/pages/settings/theme.install.vue
+++ b/src/client/pages/settings/theme.install.vue
@@ -4,16 +4,15 @@
<FormTextarea v-model:value="installThemeCode">
<span>{{ $ts._theme.code }}</span>
</FormTextarea>
- <FormButton @click="() => preview(installThemeCode)" :disabled="installThemeCode == null" inline><Fa :icon="faEye"/> {{ $ts.preview }}</FormButton>
+ <FormButton @click="() => preview(installThemeCode)" :disabled="installThemeCode == null" inline><i class="fas fa-eye"></i> {{ $ts.preview }}</FormButton>
</FormGroup>
- <FormButton @click="() => install(installThemeCode)" :disabled="installThemeCode == null" primary inline><Fa :icon="faCheck"/> {{ $ts.install }}</FormButton>
+ <FormButton @click="() => install(installThemeCode)" :disabled="installThemeCode == null" primary inline><i class="fas fa-check"></i> {{ $ts.install }}</FormButton>
</FormBase>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye } from '@fortawesome/free-solid-svg-icons';
import * as JSON5 from 'json5';
import FormTextarea from '@client/components/form/textarea.vue';
import FormSelect from '@client/components/form/select.vue';
@@ -45,10 +44,9 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts._theme.install,
- icon: faDownload
+ icon: 'fas fa-download'
},
installThemeCode: null,
- faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye
}
},
diff --git a/src/client/pages/settings/theme.manage.vue b/src/client/pages/settings/theme.manage.vue
index ea9d5949ff..7cc7a0169a 100644
--- a/src/client/pages/settings/theme.manage.vue
+++ b/src/client/pages/settings/theme.manage.vue
@@ -20,14 +20,13 @@
<span>{{ $ts._theme.code }}</span>
<template #desc><button @click="copyThemeCode()" class="_textButton">{{ $ts.copy }}</button></template>
</FormTextarea>
- <FormButton @click="uninstall()" danger v-if="!builtinThemes.some(t => t.id == selectedTheme.id)"><Fa :icon="faTrashAlt"/> {{ $ts.uninstall }}</FormButton>
+ <FormButton @click="uninstall()" danger v-if="!builtinThemes.some(t => t.id == selectedTheme.id)"><i class="fas fa-trash-alt"></i> {{ $ts.uninstall }}</FormButton>
</template>
</FormBase>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye } from '@fortawesome/free-solid-svg-icons';
import * as JSON5 from 'json5';
import FormTextarea from '@client/components/form/textarea.vue';
import FormSelect from '@client/components/form/select.vue';
@@ -60,12 +59,11 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts._theme.manage,
- icon: faFolderOpen
+ icon: 'fas fa-folder-open'
},
installedThemes: getThemes(),
builtinThemes,
selectedThemeId: null,
- faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye
}
},
diff --git a/src/client/pages/settings/theme.vue b/src/client/pages/settings/theme.vue
index 606e10ab7a..1eb0d68be5 100644
--- a/src/client/pages/settings/theme.vue
+++ b/src/client/pages/settings/theme.vue
@@ -71,22 +71,21 @@
<FormButton primary v-else @click="wallpaper = null">{{ $ts.removeWallpaper }}</FormButton>
<FormGroup>
- <FormLink to="https://assets.msky.cafe/theme/list" external><template #icon><Fa :icon="faGlobe"/></template>{{ $ts._theme.explore }}</FormLink>
- <FormLink to="/settings/theme/install"><template #icon><Fa :icon="faDownload"/></template>{{ $ts._theme.install }}</FormLink>
+ <FormLink to="https://assets.msky.cafe/theme/list" external><template #icon><i class="fas fa-globe"></i></template>{{ $ts._theme.explore }}</FormLink>
+ <FormLink to="/settings/theme/install"><template #icon><i class="fas fa-download"></i></template>{{ $ts._theme.install }}</FormLink>
</FormGroup>
<FormGroup>
- <FormLink to="/theme-editor"><template #icon><Fa :icon="faPaintRoller"/></template>{{ $ts._theme.make }}</FormLink>
- <!--<FormLink to="/advanced-theme-editor"><template #icon><Fa :icon="faPaintRoller"/></template>{{ $ts._theme.make }} ({{ $ts.advanced }})</FormLink>-->
+ <FormLink to="/theme-editor"><template #icon><i class="fas fa-paint-roller"></i></template>{{ $ts._theme.make }}</FormLink>
+ <!--<FormLink to="/advanced-theme-editor"><template #icon><i class="fas fa-paint-roller"></i></template>{{ $ts._theme.make }} ({{ $ts.advanced }})</FormLink>-->
</FormGroup>
- <FormLink to="/settings/theme/manage"><template #icon><Fa :icon="faFolderOpen"/></template>{{ $ts._theme.manage }}<template #suffix>{{ themesCount }}</template></FormLink>
+ <FormLink to="/settings/theme/manage"><template #icon><i class="fas fa-folder-open"></i></template>{{ $ts._theme.manage }}<template #suffix>{{ themesCount }}</template></FormLink>
</FormBase>
</template>
<script lang="ts">
import { computed, defineComponent, onActivated, onMounted, ref, watch } from 'vue';
-import { faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye, faGlobe, faPaintRoller } from '@fortawesome/free-solid-svg-icons';
import FormSwitch from '@client/components/form/switch.vue';
import FormSelect from '@client/components/form/select.vue';
import FormBase from '@client/components/form/base.vue';
@@ -117,7 +116,7 @@ export default defineComponent({
setup(props, { emit }) {
const INFO = {
title: i18n.locale.theme,
- icon: faPalette
+ icon: 'fas fa-palette'
};
const installedThemes = ref(getThemes());
@@ -191,7 +190,6 @@ export default defineComponent({
wallpaper.value = file.url;
});
},
- faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye, faGlobe, faPaintRoller,
};
}
});
diff --git a/src/client/pages/settings/update.vue b/src/client/pages/settings/update.vue
index d7b2adae56..8000327d0c 100644
--- a/src/client/pages/settings/update.vue
+++ b/src/client/pages/settings/update.vue
@@ -30,7 +30,6 @@
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
-import { faInfoCircle, faSyncAlt } from '@fortawesome/free-solid-svg-icons';
import FormSwitch from '@client/components/form/switch.vue';
import FormSelect from '@client/components/form/select.vue';
import FormLink from '@client/components/form/link.vue';
@@ -61,7 +60,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: 'Misskey Update',
- icon: faSyncAlt
+ icon: 'fas fa-sync-alt'
},
version,
instanceName,
diff --git a/src/client/pages/settings/word-mute.vue b/src/client/pages/settings/word-mute.vue
index 79de2ebbdf..fe3fece844 100644
--- a/src/client/pages/settings/word-mute.vue
+++ b/src/client/pages/settings/word-mute.vue
@@ -25,14 +25,13 @@
</FormKeyValueView>
</div>
</div>
- <FormButton @click="save()" primary inline :disabled="!changed"><Fa :icon="faSave"/> {{ $ts.save }}</FormButton>
+ <FormButton @click="save()" primary inline :disabled="!changed"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
</FormBase>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faCommentSlash, faSave } from '@fortawesome/free-solid-svg-icons';
import FormTextarea from '@client/components/form/textarea.vue';
import FormBase from '@client/components/form/base.vue';
import FormKeyValueView from '@client/components/form/key-value-view.vue';
@@ -59,14 +58,13 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.wordMute,
- icon: faCommentSlash
+ icon: 'fas fa-comment-slash'
},
tab: 'soft',
softMutedWords: '',
hardMutedWords: '',
hardWordMutedNotesCount: null,
changed: false,
- faSave,
}
},
diff --git a/src/client/pages/share.vue b/src/client/pages/share.vue
index 313b73b9cb..67e598fa8f 100644
--- a/src/client/pages/share.vue
+++ b/src/client/pages/share.vue
@@ -13,7 +13,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faShareAlt } from '@fortawesome/free-solid-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import XPostForm from '@client/components/post-form.vue';
import * as os from '@client/os';
@@ -29,7 +28,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.share,
- icon: faShareAlt
+ icon: 'fas fa-share-alt'
},
title: null,
text: null,
@@ -37,7 +36,6 @@ export default defineComponent({
initialText: null,
posted: false,
- faShareAlt
}
},
diff --git a/src/client/pages/tag.vue b/src/client/pages/tag.vue
index 813181dd1f..3ca9fe5c0c 100644
--- a/src/client/pages/tag.vue
+++ b/src/client/pages/tag.vue
@@ -6,7 +6,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faHashtag } from '@fortawesome/free-solid-svg-icons';
import Progress from '@client/scripts/loading';
import XNotes from '@client/components/notes.vue';
import * as symbols from '@client/symbols';
@@ -27,7 +26,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.tag,
- icon: faHashtag
+ icon: 'fas fa-hashtag'
},
pagination: {
endpoint: 'notes/search-by-tag',
@@ -36,7 +35,6 @@ export default defineComponent({
tag: this.tag,
})
},
- faHashtag
};
},
diff --git a/src/client/pages/test.vue b/src/client/pages/test.vue
index 252fa1c828..9a06d31090 100644
--- a/src/client/pages/test.vue
+++ b/src/client/pages/test.vue
@@ -132,7 +132,6 @@
<script lang="ts">
import { defineComponent, defineAsyncComponent } from 'vue';
-import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
import MkSwitch from '@client/components/ui/switch.vue';
@@ -154,7 +153,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: 'TEST',
- icon: faExclamationTriangle
+ icon: 'fas fa-exclamation-triangle'
},
dialogTitle: 'Hello',
dialogBody: 'World!',
diff --git a/src/client/pages/theme-editor.vue b/src/client/pages/theme-editor.vue
index db273746a8..ce8bae4ff5 100644
--- a/src/client/pages/theme-editor.vue
+++ b/src/client/pages/theme-editor.vue
@@ -42,7 +42,7 @@
</FormTextarea>
<FormButton @click="applyThemeCode" primary>{{ $ts.apply }}</FormButton>
</FormGroup>
- <FormButton v-else @click="codeEnabled = true"><Fa :icon="faCode"/> {{ $ts.editCode }}</FormButton>
+ <FormButton v-else @click="codeEnabled = true"><i class="fas fa-code"></i> {{ $ts.editCode }}</FormButton>
<FormGroup v-if="descriptionEnabled">
<FormTextarea v-model:value="description">
@@ -52,15 +52,14 @@
<FormButton v-else @click="descriptionEnabled = true">{{ $ts.addDescription }}</FormButton>
<FormGroup>
- <FormButton @click="showPreview"><Fa :icon="faEye"/> {{ $ts.preview }}</FormButton>
- <FormButton @click="saveAs" primary><Fa :icon="faSave"/> {{ $ts.saveAs }}</FormButton>
+ <FormButton @click="showPreview"><i class="fas fa-eye"></i> {{ $ts.preview }}</FormButton>
+ <FormButton @click="saveAs" primary><i class="fas fa-save"></i> {{ $ts.saveAs }}</FormButton>
</FormGroup>
</FormBase>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faPalette, faSave, faEye, faCode } from '@fortawesome/free-solid-svg-icons';
import { toUnicode } from 'punycode/';
import * as tinycolor from 'tinycolor2';
import { v4 as uuid} from 'uuid';
@@ -90,7 +89,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.themeEditor,
- icon: faPalette,
+ icon: 'fas fa-palette',
},
theme: {
base: 'light',
@@ -129,7 +128,6 @@ export default defineComponent({
{ color: 'pink', forLight: '#84667d', forDark: '#e4d1e0', forPreview: '#b12390' },
],
changed: false,
- faPalette, faSave, faEye, faCode,
}
},
diff --git a/src/client/pages/timeline.tutorial.vue b/src/client/pages/timeline.tutorial.vue
index bcbf16acc7..620994c0da 100644
--- a/src/client/pages/timeline.tutorial.vue
+++ b/src/client/pages/timeline.tutorial.vue
@@ -1,6 +1,6 @@
<template>
<div class="_card tbkwesmv">
- <div class="_title"><Fa :icon="faInfoCircle"/> {{ $ts._tutorial.title }}</div>
+ <div class="_title"><i class="fas fa-info-circle"></i> {{ $ts._tutorial.title }}</div>
<div class="_content" v-if="tutorial === 0">
<div>{{ $ts._tutorial.step1_1 }}</div>
<div>{{ $ts._tutorial.step1_2 }}</div>
@@ -52,22 +52,21 @@
<div class="_footer navigation">
<div class="step">
<button class="arrow _button" @click="tutorial--" :disabled="tutorial === 0">
- <Fa :icon="faChevronLeft"/>
+ <i class="fas fa-chevron-left"></i>
</button>
<span>{{ tutorial + 1 }} / 7</span>
<button class="arrow _button" @click="tutorial++" :disabled="tutorial === 6">
- <Fa :icon="faChevronRight"/>
+ <i class="fas fa-chevron-right"></i>
</button>
</div>
- <MkButton class="ok" @click="tutorial = -1" primary v-if="tutorial === 6"><Fa :icon="faCheck"/> {{ $ts.gotIt }}</MkButton>
- <MkButton class="ok" @click="tutorial++" primary v-else><Fa :icon="faCheck"/> {{ $ts.next }}</MkButton>
+ <MkButton class="ok" @click="tutorial = -1" primary v-if="tutorial === 6"><i class="fas fa-check"></i> {{ $ts.gotIt }}</MkButton>
+ <MkButton class="ok" @click="tutorial++" primary v-else><i class="fas fa-check"></i> {{ $ts.next }}</MkButton>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
-import { faInfoCircle, faChevronLeft, faChevronRight, faCheck } from '@fortawesome/free-solid-svg-icons'
import MkButton from '@client/components/ui/button.vue';
export default defineComponent({
@@ -77,7 +76,6 @@ export default defineComponent({
data() {
return {
- faInfoCircle, faChevronLeft, faChevronRight, faCheck
}
},
diff --git a/src/client/pages/timeline.vue b/src/client/pages/timeline.vue
index efad31c252..5660d0099e 100644
--- a/src/client/pages/timeline.vue
+++ b/src/client/pages/timeline.vue
@@ -4,18 +4,18 @@
<XPostForm v-if="$store.reactiveState.showFixedPostForm.value" class="post-form _block" fixed/>
<div class="tabs _block">
<div class="left">
- <button class="_button tab" @click="() => { src = 'home'; saveSrc(); }" :class="{ active: src === 'home' }" v-tooltip="$ts._timelines.home"><Fa :icon="faHome"/></button>
- <button class="_button tab" @click="() => { src = 'local'; saveSrc(); }" :class="{ active: src === 'local' }" v-tooltip="$ts._timelines.local" v-if="isLocalTimelineAvailable"><Fa :icon="faComments"/></button>
- <button class="_button tab" @click="() => { src = 'social'; saveSrc(); }" :class="{ active: src === 'social' }" v-tooltip="$ts._timelines.social" v-if="isLocalTimelineAvailable"><Fa :icon="faShareAlt"/></button>
- <button class="_button tab" @click="() => { src = 'global'; saveSrc(); }" :class="{ active: src === 'global' }" v-tooltip="$ts._timelines.global" v-if="isGlobalTimelineAvailable"><Fa :icon="faGlobe"/></button>
+ <button class="_button tab" @click="() => { src = 'home'; saveSrc(); }" :class="{ active: src === 'home' }" v-tooltip="$ts._timelines.home"><i class="fas fa-home"></i></button>
+ <button class="_button tab" @click="() => { src = 'local'; saveSrc(); }" :class="{ active: src === 'local' }" v-tooltip="$ts._timelines.local" v-if="isLocalTimelineAvailable"><i class="fas fa-comments"></i></button>
+ <button class="_button tab" @click="() => { src = 'social'; saveSrc(); }" :class="{ active: src === 'social' }" v-tooltip="$ts._timelines.social" v-if="isLocalTimelineAvailable"><i class="fas fa-share-alt"></i></button>
+ <button class="_button tab" @click="() => { src = 'global'; saveSrc(); }" :class="{ active: src === 'global' }" v-tooltip="$ts._timelines.global" v-if="isGlobalTimelineAvailable"><i class="fas fa-globe"></i></button>
<span class="divider"></span>
- <button class="_button tab" @click="() => { src = 'mentions'; saveSrc(); }" :class="{ active: src === 'mentions' }" v-tooltip="$ts.mentions"><Fa :icon="faAt"/><Fa :icon="faCircle" class="i" v-if="$i.hasUnreadMentions"/></button>
- <button class="_button tab" @click="() => { src = 'directs'; saveSrc(); }" :class="{ active: src === 'directs' }" v-tooltip="$ts.directNotes"><Fa :icon="faEnvelope"/><Fa :icon="faCircle" class="i" v-if="$i.hasUnreadSpecifiedNotes"/></button>
+ <button class="_button tab" @click="() => { src = 'mentions'; saveSrc(); }" :class="{ active: src === 'mentions' }" v-tooltip="$ts.mentions"><i class="fas fa-at"></i><i v-if="$i.hasUnreadMentions" class="fas fa-circle i"></i></button>
+ <button class="_button tab" @click="() => { src = 'directs'; saveSrc(); }" :class="{ active: src === 'directs' }" v-tooltip="$ts.directNotes"><i class="fas fa-envelope"></i><i v-if="$i.hasUnreadSpecifiedNotes" class="fas fa-circle i"></i></button>
</div>
<div class="right">
- <button class="_button tab" @click="chooseChannel" :class="{ active: src === 'channel' }" v-tooltip="$ts.channel"><Fa :icon="faSatelliteDish"/><Fa :icon="faCircle" class="i" v-if="$i.hasUnreadChannel"/></button>
- <button class="_button tab" @click="chooseAntenna" :class="{ active: src === 'antenna' }" v-tooltip="$ts.antennas"><Fa :icon="faSatellite"/><Fa :icon="faCircle" class="i" v-if="$i.hasUnreadAntenna"/></button>
- <button class="_button tab" @click="chooseList" :class="{ active: src === 'list' }" v-tooltip="$ts.lists"><Fa :icon="faListUl"/></button>
+ <button class="_button tab" @click="chooseChannel" :class="{ active: src === 'channel' }" v-tooltip="$ts.channel"><i class="fas fa-satellite-dish"></i><i v-if="$i.hasUnreadChannel" class="fas fa-circle i"></i></button>
+ <button class="_button tab" @click="chooseAntenna" :class="{ active: src === 'antenna' }" v-tooltip="$ts.antennas"><i class="fas fa-satellite"></i><i v-if="$i.hasUnreadAntenna" class="fas fa-circle i"></i></button>
+ <button class="_button tab" @click="chooseList" :class="{ active: src === 'list' }" v-tooltip="$ts.lists"><i class="fas fa-list-ul"></i></button>
</div>
</div>
<XTimeline ref="tl"
@@ -36,8 +36,6 @@
<script lang="ts">
import { defineComponent, defineAsyncComponent, computed } from 'vue';
-import { faAngleDown, faAngleUp, faHome, faShareAlt, faGlobe, faListUl, faSatellite, faSatelliteDish, faCircle, faEllipsisH, faPencilAlt, faAt } from '@fortawesome/free-solid-svg-icons';
-import { faComments, faEnvelope, faCalendarAlt } from '@fortawesome/free-regular-svg-icons';
import Progress from '@client/scripts/loading';
import XTimeline from '@client/components/timeline.vue';
import XPostForm from '@client/components/post-form.vue';
@@ -64,14 +62,13 @@ export default defineComponent({
queue: 0,
[symbols.PAGE_INFO]: computed(() => ({
title: this.$ts.timeline,
- icon: this.src === 'local' ? faComments : this.src === 'social' ? faShareAlt : this.src === 'global' ? faGlobe : faHome,
+ icon: this.src === 'local' ? 'fas fa-comments' : this.src === 'social' ? 'fas fa-share-alt' : this.src === 'global' ? 'fas fa-globe' : 'fas fa-home',
actions: [{
- icon: faCalendarAlt,
+ icon: 'fas fa-calendar-alt',
text: this.$ts.jumpToSpecifiedDate,
handler: this.timetravel
}]
})),
- faAngleDown, faAngleUp, faHome, faShareAlt, faGlobe, faComments, faListUl, faSatellite, faSatelliteDish, faCircle, faEllipsisH, faAt, faEnvelope,
};
},
diff --git a/src/client/pages/user-ap-info.vue b/src/client/pages/user-ap-info.vue
index 648ecdb10a..c08a352571 100644
--- a/src/client/pages/user-ap-info.vue
+++ b/src/client/pages/user-ap-info.vue
@@ -58,7 +58,6 @@
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
-import { faInfoCircle } from '@fortawesome/free-solid-svg-icons';
import FormObjectView from '@client/components/form/object-view.vue';
import FormTextarea from '@client/components/form/textarea.vue';
import FormLink from '@client/components/form/link.vue';
@@ -96,7 +95,7 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.userInfo,
- icon: faInfoCircle
+ icon: 'fas fa-info-circle'
},
user: null,
apPromiseFactory: null,
diff --git a/src/client/pages/user-info.vue b/src/client/pages/user-info.vue
index 06f2e4270d..51bd5016bb 100644
--- a/src/client/pages/user-info.vue
+++ b/src/client/pages/user-info.vue
@@ -1,12 +1,34 @@
<template>
<FormBase>
- <FormGroup v-if="user">
- <template #label><MkAcct :user="user"/></template>
+ <FormSuspense :p="init">
+ <div class="_formItem aeakzknw">
+ <MkAvatar class="avatar" :user="user" :show-indicator="true"/>
+ </div>
- <FormKeyValueView>
- <template #key>ID</template>
- <template #value><span class="_monospace">{{ user.id }}</span></template>
- </FormKeyValueView>
+ <FormLink :to="userPage(user)">Profile</FormLink>
+
+ <FormGroup>
+ <FormKeyValueView>
+ <template #key>Acct</template>
+ <template #value><span class="_monospace">{{ acct(user) }}</span></template>
+ </FormKeyValueView>
+
+ <FormKeyValueView>
+ <template #key>ID</template>
+ <template #value><span class="_monospace">{{ user.id }}</span></template>
+ </FormKeyValueView>
+ </FormGroup>
+
+ <FormGroup v-if="iAmModerator">
+ <FormSwitch v-if="user.host == null && $i.isAdmin && (moderator || !user.isAdmin)" @update:value="toggleModerator" v-model:value="moderator">{{ $ts.moderator }}</FormSwitch>
+ <FormSwitch @update:value="toggleSilence" v-model:value="silenced">{{ $ts.silence }}</FormSwitch>
+ <FormSwitch @update:value="toggleSuspend" v-model:value="suspended">{{ $ts.suspend }}</FormSwitch>
+ </FormGroup>
+
+ <FormGroup>
+ <FormButton v-if="user.host != null" @click="updateRemoteUser"><i class="fas fa-sync"></i> {{ $ts.updateRemoteUser }}</FormButton>
+ <FormButton v-if="user.host == null && iAmModerator" @click="resetPassword"><i class="fas fa-key"></i> {{ $ts.resetPassword }}</FormButton>
+ </FormGroup>
<FormGroup>
<FormLink :to="`/user-ap-info/${user.id}`">ActivityPub</FormLink>
@@ -28,15 +50,15 @@
<FormObjectView tall :value="user">
<span>Raw</span>
</FormObjectView>
- </FormGroup>
+ </FormSuspense>
</FormBase>
</template>
<script lang="ts">
import { computed, defineAsyncComponent, defineComponent } from 'vue';
-import { faExternalLinkAlt, faInfoCircle } from '@fortawesome/free-solid-svg-icons';
import FormObjectView from '@client/components/form/object-view.vue';
import FormTextarea from '@client/components/form/textarea.vue';
+import FormSwitch from '@client/components/form/switch.vue';
import FormLink from '@client/components/form/link.vue';
import FormBase from '@client/components/form/base.vue';
import FormGroup from '@client/components/form/group.vue';
@@ -48,11 +70,13 @@ import number from '@client/filters/number';
import bytes from '@client/filters/bytes';
import * as symbols from '@client/symbols';
import { url } from '@client/config';
+import { userPage, acct } from '@client/filters/user';
export default defineComponent({
components: {
FormBase,
FormTextarea,
+ FormSwitch,
FormObjectView,
FormButton,
FormLink,
@@ -71,33 +95,151 @@ export default defineComponent({
data() {
return {
[symbols.PAGE_INFO]: computed(() => ({
- title: this.$ts.userInfo,
- icon: faInfoCircle,
+ title: this.user ? acct(this.user) : this.$ts.userInfo,
+ icon: 'fas fa-info-circle',
actions: this.user ? [this.user.url ? {
text: this.user.url,
- icon: faExternalLinkAlt,
+ icon: 'fas fa-external-link-alt',
handler: () => {
window.open(this.user.url, '_blank');
}
} : undefined].filter(x => x !== undefined) : [],
})),
+ init: null,
user: null,
+ info: null,
+ moderator: false,
+ silenced: false,
+ suspended: false,
+ }
+ },
+
+ computed: {
+ iAmModerator(): boolean {
+ return this.$i && (this.$i.isAdmin || this.$i.isModerator);
}
},
- mounted() {
- this.fetch();
+ watch: {
+ userId: {
+ handler() {
+ this.init = this.createFetcher();
+ },
+ immediate: true
+ }
},
methods: {
number,
bytes,
+ userPage,
+ acct,
+
+ createFetcher() {
+ if (this.iAmModerator) {
+ return () => Promise.all([os.api('users/show', {
+ userId: this.userId
+ }), os.api('admin/show-user', {
+ userId: this.userId
+ })]).then(([user, info]) => {
+ this.user = user;
+ this.info = info;
+ this.moderator = this.info.isModerator;
+ this.silenced = this.info.isSilenced;
+ this.suspended = this.info.isSuspended;
+ });
+ } else {
+ return () => os.api('users/show', {
+ userId: this.userId
+ }).then((user) => {
+ this.user = user;
+ });
+ }
+ },
+
+ refreshUser() {
+ this.init = this.createFetcher();
+ },
- async fetch() {
- this.user = await os.api('users/show', {
- userId: this.userId
+ async updateRemoteUser() {
+ await os.apiWithDialog('federation/update-remote-user', { userId: this.user.id });
+ this.refreshUser();
+ },
+
+ async resetPassword() {
+ os.apiWithDialog('admin/reset-password', {
+ userId: this.user.id,
+ }, undefined, ({ password }) => {
+ os.dialog({
+ type: 'success',
+ text: this.$t('newPasswordIs', { password })
+ });
});
- }
+ },
+
+ async toggleSilence(v) {
+ const confirm = await os.dialog({
+ type: 'warning',
+ showCancelButton: true,
+ text: v ? this.$ts.silenceConfirm : this.$ts.unsilenceConfirm,
+ });
+ if (confirm.canceled) {
+ this.silenced = !v;
+ } else {
+ await os.api(v ? 'admin/silence-user' : 'admin/unsilence-user', { userId: this.user.id });
+ await this.refreshUser();
+ }
+ },
+
+ async toggleSuspend(v) {
+ const confirm = await os.dialog({
+ type: 'warning',
+ showCancelButton: true,
+ text: v ? this.$ts.suspendConfirm : this.$ts.unsuspendConfirm,
+ });
+ if (confirm.canceled) {
+ this.suspended = !v;
+ } else {
+ await os.api(v ? 'admin/suspend-user' : 'admin/unsuspend-user', { userId: this.user.id });
+ await this.refreshUser();
+ }
+ },
+
+ async toggleModerator(v) {
+ await os.api(v ? 'admin/moderators/add' : 'admin/moderators/remove', { userId: this.user.id });
+ await this.refreshUser();
+ },
+
+ async deleteAllFiles() {
+ const confirm = await os.dialog({
+ type: 'warning',
+ showCancelButton: true,
+ text: this.$ts.deleteAllFilesConfirm,
+ });
+ if (confirm.canceled) return;
+ const process = async () => {
+ await os.api('admin/delete-all-files-of-a-user', { userId: this.user.id });
+ os.success();
+ };
+ await process().catch(e => {
+ os.dialog({
+ type: 'error',
+ text: e.toString()
+ });
+ });
+ await this.refreshUser();
+ },
}
});
</script>
+
+<style lang="scss" scoped>
+.aeakzknw {
+ > .avatar {
+ display: block;
+ margin: 0 auto;
+ width: 64px;
+ height: 64px;
+ }
+}
+</style>
diff --git a/src/client/pages/user/index.activity.vue b/src/client/pages/user/index.activity.vue
index 3eca1ab210..9101c8ae5f 100644
--- a/src/client/pages/user/index.activity.vue
+++ b/src/client/pages/user/index.activity.vue
@@ -1,6 +1,6 @@
<template>
<MkContainer>
- <template #header><Fa :icon="faChartBar" style="margin-right: 0.5em;"/>{{ $ts.activity }}</template>
+ <template #header><i class="fas fa-chart-bar" style="margin-right: 0.5em;"></i>{{ $ts.activity }}</template>
<div style="padding: 8px;">
<div ref="chart"></div>
@@ -11,7 +11,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
import ApexCharts from 'apexcharts';
-import { faChartBar } from '@fortawesome/free-solid-svg-icons';
import * as os from '@client/os';
import MkContainer from '@client/components/ui/container.vue';
@@ -35,7 +34,6 @@ export default defineComponent({
fetching: true,
data: [],
peak: null,
- faChartBar,
};
},
mounted() {
diff --git a/src/client/pages/user/index.photos.vue b/src/client/pages/user/index.photos.vue
index 21d84cef4f..a899b116e5 100644
--- a/src/client/pages/user/index.photos.vue
+++ b/src/client/pages/user/index.photos.vue
@@ -1,6 +1,6 @@
<template>
<MkContainer :max-height="300" :foldable="true">
- <template #header><Fa :icon="faImage" style="margin-right: 0.5em;"/>{{ $ts.images }}</template>
+ <template #header><i class="fas fa-image" style="margin-right: 0.5em;"></i>{{ $ts.images }}</template>
<div class="ujigsodd">
<MkLoading v-if="fetching"/>
<div class="stream" v-if="!fetching && images.length > 0">
@@ -19,7 +19,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faImage } from '@fortawesome/free-solid-svg-icons';
import { getStaticImageUrl } from '@client/scripts/get-static-image-url';
import notePage from '../../filters/note';
import * as os from '@client/os';
@@ -41,7 +40,6 @@ export default defineComponent({
return {
fetching: true,
images: [],
- faImage
};
},
mounted() {
diff --git a/src/client/pages/user/index.vue b/src/client/pages/user/index.vue
index 92656fff2c..207b44f631 100644
--- a/src/client/pages/user/index.vue
+++ b/src/client/pages/user/index.vue
@@ -34,15 +34,15 @@
</div>
<div class="fields system">
<dl class="field" v-if="user.location">
- <dt class="name"><Fa :icon="faMapMarker" fixed-width/> {{ $ts.location }}</dt>
+ <dt class="name"><i class="fas fa-map-marker fa-fw"></i> {{ $ts.location }}</dt>
<dd class="value">{{ user.location }}</dd>
</dl>
<dl class="field" v-if="user.birthday">
- <dt class="name"><Fa :icon="faBirthdayCake" fixed-width/> {{ $ts.birthday }}</dt>
+ <dt class="name"><i class="fas fa-birthday-cake fa-fw"></i> {{ $ts.birthday }}</dt>
<dd class="value">{{ user.birthday.replace('-', '/').replace('-', '/') }} ({{ $t('yearsOld', { age }) }})</dd>
</dl>
<dl class="field">
- <dt class="name"><Fa :icon="faCalendarAlt" fixed-width/> {{ $ts.registeredDate }}</dt>
+ <dt class="name"><i class="fas fa-calendar-alt fa-fw"></i> {{ $ts.registeredDate }}</dt>
<dd class="value">{{ new Date(user.createdAt).toLocaleString() }} (<MkTime :time="user.createdAt"/>)</dd>
</dl>
</div>
@@ -62,19 +62,19 @@
<div class="main">
<div class="nav _gap">
<MkA :to="userPage(user)" :class="{ active: page === 'index' }" class="link">
- <Fa :icon="faCommentAlt" class="icon"/>
+ <i class="fas fa-comment-alt icon"></i>
<span>{{ $ts.notes }}</span>
</MkA>
<MkA :to="userPage(user, 'clips')" :class="{ active: page === 'clips' }" class="link">
- <Fa :icon="faPaperclip" class="icon"/>
+ <i class="fas fa-paperclip icon"></i>
<span>{{ $ts.clips }}</span>
</MkA>
<MkA :to="userPage(user, 'pages')" :class="{ active: page === 'pages' }" class="link">
- <Fa :icon="faFileAlt" class="icon"/>
+ <i class="fas fa-file-alt icon"></i>
<span>{{ $ts.pages }}</span>
</MkA>
<div class="actions">
- <button @click="menu" class="menu _button"><Fa :icon="faEllipsisH"/></button>
+ <button @click="menu" class="menu _button"><i class="fas fa-ellipsis-h"></i></button>
<MkFollowButton v-if="!$i || $i.id != user.id" :user="user" :inline="true" :transparent="false" :full="true" large class="koudoku"/>
</div>
</div>
@@ -95,8 +95,8 @@
</div>
<div class="ftskorzw narrow _root" v-else-if="user && narrow === true" v-size="{ max: [500] }">
<!-- TODO -->
- <!-- <div class="punished" v-if="user.isSuspended"><Fa :icon="faExclamationTriangle" style="margin-right: 8px;"/> {{ $ts.userSuspended }}</div> -->
- <!-- <div class="punished" v-if="user.isSilenced"><Fa :icon="faExclamationTriangle" style="margin-right: 8px;"/> {{ $ts.userSilenced }}</div> -->
+ <!-- <div class="punished" v-if="user.isSuspended"><i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i> {{ $ts.userSuspended }}</div> -->
+ <!-- <div class="punished" v-if="user.isSilenced"><i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i> {{ $ts.userSilenced }}</div> -->
<div class="profile">
<MkRemoteCaution v-if="user.host != null" :href="user.url" class="warn"/>
@@ -109,15 +109,15 @@
<MkUserName class="name" :user="user" :nowrap="true"/>
<div class="bottom">
<span class="username"><MkAcct :user="user" :detail="true" /></span>
- <span v-if="user.isAdmin" :title="$ts.isAdmin" style="color: var(--badge);"><Fa :icon="faBookmark"/></span>
- <span v-if="!user.isAdmin && user.isModerator" :title="$ts.isModerator" style="color: var(--badge);"><Fa :icon="farBookmark"/></span>
- <span v-if="user.isLocked" :title="$ts.isLocked"><Fa :icon="faLock"/></span>
- <span v-if="user.isBot" :title="$ts.isBot"><Fa :icon="faRobot"/></span>
+ <span v-if="user.isAdmin" :title="$ts.isAdmin" style="color: var(--badge);"><i class="fas fa-bookmark"></i></span>
+ <span v-if="!user.isAdmin && user.isModerator" :title="$ts.isModerator" style="color: var(--badge);"><i class="far fa-bookmark"></i></span>
+ <span v-if="user.isLocked" :title="$ts.isLocked"><i class="fas fa-lock"></i></span>
+ <span v-if="user.isBot" :title="$ts.isBot"><i class="fas fa-robot"></i></span>
</div>
</div>
<span class="followed" v-if="$i && $i.id != user.id && user.isFollowed">{{ $ts.followsYou }}</span>
<div class="actions" v-if="$i">
- <button @click="menu" class="menu _button"><Fa :icon="faEllipsisH"/></button>
+ <button @click="menu" class="menu _button"><i class="fas fa-ellipsis-h"></i></button>
<MkFollowButton v-if="$i.id != user.id" :user="user" :inline="true" :transparent="false" :full="true" class="koudoku"/>
</div>
</div>
@@ -126,10 +126,10 @@
<MkUserName :user="user" :nowrap="false" class="name"/>
<div class="bottom">
<span class="username"><MkAcct :user="user" :detail="true" /></span>
- <span v-if="user.isAdmin" :title="$ts.isAdmin" style="color: var(--badge);"><Fa :icon="faBookmark"/></span>
- <span v-if="!user.isAdmin && user.isModerator" :title="$ts.isModerator" style="color: var(--badge);"><Fa :icon="farBookmark"/></span>
- <span v-if="user.isLocked" :title="$ts.isLocked"><Fa :icon="faLock"/></span>
- <span v-if="user.isBot" :title="$ts.isBot"><Fa :icon="faRobot"/></span>
+ <span v-if="user.isAdmin" :title="$ts.isAdmin" style="color: var(--badge);"><i class="fas fa-bookmark"></i></span>
+ <span v-if="!user.isAdmin && user.isModerator" :title="$ts.isModerator" style="color: var(--badge);"><i class="far fa-bookmark"></i></span>
+ <span v-if="user.isLocked" :title="$ts.isLocked"><i class="fas fa-lock"></i></span>
+ <span v-if="user.isBot" :title="$ts.isBot"><i class="fas fa-robot"></i></span>
</div>
</div>
<div class="description">
@@ -138,15 +138,15 @@
</div>
<div class="fields system">
<dl class="field" v-if="user.location">
- <dt class="name"><Fa :icon="faMapMarker" fixed-width/> {{ $ts.location }}</dt>
+ <dt class="name"><i class="fas fa-map-marker fa-fw"></i> {{ $ts.location }}</dt>
<dd class="value">{{ user.location }}</dd>
</dl>
<dl class="field" v-if="user.birthday">
- <dt class="name"><Fa :icon="faBirthdayCake" fixed-width/> {{ $ts.birthday }}</dt>
+ <dt class="name"><i class="fas fa-birthday-cake fa-fw"></i> {{ $ts.birthday }}</dt>
<dd class="value">{{ user.birthday.replace('-', '/').replace('-', '/') }} ({{ $t('yearsOld', { age }) }})</dd>
</dl>
<dl class="field">
- <dt class="name"><Fa :icon="faCalendarAlt" fixed-width/> {{ $ts.registeredDate }}</dt>
+ <dt class="name"><i class="fas fa-calendar-alt fa-fw"></i> {{ $ts.registeredDate }}</dt>
<dd class="value">{{ new Date(user.createdAt).toLocaleString() }} (<MkTime :time="user.createdAt"/>)</dd>
</dl>
</div>
@@ -180,22 +180,22 @@
<div class="contents">
<div class="nav _gap">
<MkA :to="userPage(user)" :class="{ active: page === 'index' }" class="link">
- <Fa :icon="faCommentAlt" class="icon"/>
+ <i class="fas fa-comment-alt icon"></i>
<span>{{ $ts.notes }}</span>
</MkA>
<MkA :to="userPage(user, 'clips')" :class="{ active: page === 'clips' }" class="link">
- <Fa :icon="faPaperclip" class="icon"/>
+ <i class="fas fa-paperclip icon"></i>
<span>{{ $ts.clips }}</span>
</MkA>
<MkA :to="userPage(user, 'pages')" :class="{ active: page === 'pages' }" class="link">
- <Fa :icon="faFileAlt" class="icon"/>
+ <i class="fas fa-file-alt icon"></i>
<span>{{ $ts.pages }}</span>
</MkA>
</div>
<template v-if="page === 'index'">
<div>
- <div v-if="user.pinnedNotes.length > 0">
+ <div v-if="user.pinnedNotes.length > 0" class="_gap">
<XNote v-for="note in user.pinnedNotes" class="note _block" :note="note" @update:note="pinnedNoteUpdated(note, $event)" :key="note.id" :pinned="true"/>
</div>
<MkInfo v-else-if="$i && $i.id === user.id">{{ $ts.userPagePinTip }}</MkInfo>
@@ -219,8 +219,6 @@
<script lang="ts">
import { defineComponent, defineAsyncComponent, computed } from 'vue';
-import { faExclamationTriangle, faEllipsisH, faRobot, faLock, faBookmark, faChartBar, faImage, faBirthdayCake, faMapMarker, faPaperclip, faFileAlt } from '@fortawesome/free-solid-svg-icons';
-import { faCalendarAlt, faBookmark as farBookmark, faCommentAlt } from '@fortawesome/free-regular-svg-icons';
import * as age from 's-age';
import XUserTimeline from './index.timeline.vue';
import XNote from '@client/components/note.vue';
@@ -284,7 +282,6 @@ export default defineComponent({
error: null,
parallaxAnimationId: null,
narrow: null,
- faExclamationTriangle, faEllipsisH, faRobot, faLock, faBookmark, farBookmark, faChartBar, faImage, faBirthdayCake, faMapMarker, faCalendarAlt, faCommentAlt, faPaperclip, faFileAlt,
};
},
diff --git a/src/client/pages/v.vue b/src/client/pages/v.vue
index 37a850b625..4440e8070e 100644
--- a/src/client/pages/v.vue
+++ b/src/client/pages/v.vue
@@ -12,7 +12,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faInfoCircle } from '@fortawesome/free-solid-svg-icons';
import { version } from '@client/config';
import * as symbols from '@client/symbols';
@@ -24,7 +23,6 @@ export default defineComponent({
icon: null
},
version,
- faInfoCircle
}
},
});
diff --git a/src/client/pages/welcome.entrance.a.vue b/src/client/pages/welcome.entrance.a.vue
index 7b02c44923..da3c694265 100644
--- a/src/client/pages/welcome.entrance.a.vue
+++ b/src/client/pages/welcome.entrance.a.vue
@@ -43,7 +43,7 @@
<template #n><b>{{ onlineUsersCount }}</b></template>
</I18n>
</div>
- <button class="_button _acrylic menu" @click="showMenu"><Fa :icon="faEllipsisH"/></button>
+ <button class="_button _acrylic menu" @click="showMenu"><i class="fas fa-ellipsis-h"></i></button>
</div>
</div>
</div>
@@ -52,7 +52,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faEllipsisH, faInfoCircle, faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
import { toUnicode } from 'punycode/';
import XSigninDialog from '@client/components/signin-dialog.vue';
import XSignupDialog from '@client/components/signup-dialog.vue';
@@ -80,7 +79,6 @@ export default defineComponent({
stats: null,
tags: [],
onlineUsersCount: null,
- faEllipsisH
};
},
@@ -121,19 +119,19 @@ export default defineComponent({
showMenu(ev) {
os.modalMenu([{
text: this.$t('aboutX', { x: instanceName }),
- icon: faInfoCircle,
+ icon: 'fas fa-info-circle',
action: () => {
os.pageWindow('/about');
}
}, {
text: this.$ts.aboutMisskey,
- icon: faInfoCircle,
+ icon: 'fas fa-info-circle',
action: () => {
os.pageWindow('/about-misskey');
}
}, null, {
text: this.$ts.help,
- icon: faQuestionCircle,
+ icon: 'fas fa-question-circle',
action: () => {
os.pageWindow('/docs');
}
diff --git a/src/client/pages/welcome.entrance.b.vue b/src/client/pages/welcome.entrance.b.vue
index d8622e4d8e..d108eb7d94 100644
--- a/src/client/pages/welcome.entrance.b.vue
+++ b/src/client/pages/welcome.entrance.b.vue
@@ -36,7 +36,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faEllipsisH, faInfoCircle, faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
import { toUnicode } from 'punycode/';
import XSigninDialog from '@client/components/signin-dialog.vue';
import XSignupDialog from '@client/components/signup-dialog.vue';
@@ -64,7 +63,6 @@ export default defineComponent({
stats: null,
tags: [],
onlineUsersCount: null,
- faEllipsisH
};
},
@@ -105,19 +103,19 @@ export default defineComponent({
showMenu(ev) {
os.modalMenu([{
text: this.$t('aboutX', { x: instanceName }),
- icon: faInfoCircle,
+ icon: 'fas fa-info-circle',
action: () => {
os.pageWindow('/about');
}
}, {
text: this.$ts.aboutMisskey,
- icon: faInfoCircle,
+ icon: 'fas fa-info-circle',
action: () => {
os.pageWindow('/about-misskey');
}
}, null, {
text: this.$ts.help,
- icon: faQuestionCircle,
+ icon: 'fas fa-question-circle',
action: () => {
os.pageWindow('/docs');
}
diff --git a/src/client/pages/welcome.entrance.c.vue b/src/client/pages/welcome.entrance.c.vue
index 47ddf9e5ed..93811e98fb 100644
--- a/src/client/pages/welcome.entrance.c.vue
+++ b/src/client/pages/welcome.entrance.c.vue
@@ -40,7 +40,7 @@
<template #n><b>{{ onlineUsersCount }}</b></template>
</I18n>
</div>
- <button class="_button _acrylic menu" @click="showMenu"><Fa :icon="faEllipsisH"/></button>
+ <button class="_button _acrylic menu" @click="showMenu"><i class="fas fa-ellipsis-h"></i></button>
</div>
</div>
<nav class="nav">
@@ -56,7 +56,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faEllipsisH, faInfoCircle, faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
import { toUnicode } from 'punycode/';
import XSigninDialog from '@client/components/signin-dialog.vue';
import XSignupDialog from '@client/components/signup-dialog.vue';
@@ -84,7 +83,6 @@ export default defineComponent({
stats: null,
tags: [],
onlineUsersCount: null,
- faEllipsisH
};
},
@@ -125,19 +123,19 @@ export default defineComponent({
showMenu(ev) {
os.modalMenu([{
text: this.$t('aboutX', { x: instanceName }),
- icon: faInfoCircle,
+ icon: 'fas fa-info-circle',
action: () => {
os.pageWindow('/about');
}
}, {
text: this.$ts.aboutMisskey,
- icon: faInfoCircle,
+ icon: 'fas fa-info-circle',
action: () => {
os.pageWindow('/about-misskey');
}
}, null, {
text: this.$ts.help,
- icon: faQuestionCircle,
+ icon: 'fas fa-question-circle',
action: () => {
os.pageWindow('/docs');
}
diff --git a/src/client/pages/welcome.setup.vue b/src/client/pages/welcome.setup.vue
index db64f6b194..2a71e2311c 100644
--- a/src/client/pages/welcome.setup.vue
+++ b/src/client/pages/welcome.setup.vue
@@ -10,7 +10,7 @@
</MkInput>
<MkInput v-model:value="password" type="password">
<span>{{ $ts.password }}</span>
- <template #prefix><Fa :icon="faLock"/></template>
+ <template #prefix><i class="fas fa-lock"></i></template>
</MkInput>
<footer>
<MkButton primary type="submit" :disabled="submitting">{{ submitting ? $ts.processing : $ts.done }}<MkEllipsis v-if="submitting"/></MkButton>
@@ -21,7 +21,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
-import { faLock } from '@fortawesome/free-solid-svg-icons';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
import { host } from '@client/config';
@@ -40,7 +39,6 @@ export default defineComponent({
password: '',
submitting: false,
host,
- faLock
}
},