mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-04-19 13:32:24 +00:00
Code refactoring (#2785)
* chore: pretty theme menu in sidebar * refactor: renaming component templates * refactor: create custom `a-statistic` component * fix: display button text only on large screens * chore: remove loading background in overview page * fix: show `Version` text when xray version is unknown
This commit is contained in:
parent
e3120c4028
commit
db62a07fb8
24 changed files with 155 additions and 79 deletions
|
@ -473,8 +473,8 @@
|
|||
</transition>
|
||||
</a-layout>
|
||||
{{template "js" .}}
|
||||
{{template "component/themeSwitcher" .}}
|
||||
{{template "component/password" .}}
|
||||
{{template "component/aThemeSwitch" .}}
|
||||
{{template "component/aPasswordInput" .}}
|
||||
<script>
|
||||
class User {
|
||||
constructor() {
|
||||
|
|
|
@ -1,33 +1,23 @@
|
|||
{{define "menuItems"}}
|
||||
<a-menu-item key="{{ .base_path }}panel/">
|
||||
<a-icon type="dashboard"></a-icon>
|
||||
<span>
|
||||
<b>{{ i18n "menu.dashboard"}}</b>
|
||||
</span>
|
||||
<span>{{ i18n "menu.dashboard"}}</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="{{ .base_path }}panel/inbounds">
|
||||
<a-icon type="user"></a-icon>
|
||||
<span>
|
||||
<b>{{ i18n "menu.inbounds"}}</b>
|
||||
</span>
|
||||
<span>{{ i18n "menu.inbounds"}}</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="{{ .base_path }}panel/settings">
|
||||
<a-icon type="setting"></a-icon>
|
||||
<span>
|
||||
<b>{{ i18n "menu.settings"}}</b>
|
||||
</span>
|
||||
<span>{{ i18n "menu.settings"}}</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="{{ .base_path }}panel/xray">
|
||||
<a-icon type="tool"></a-icon>
|
||||
<span>
|
||||
<b>{{ i18n "menu.xray"}}</b>
|
||||
</span>
|
||||
<span>{{ i18n "menu.xray"}}</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="{{ .base_path }}logout">
|
||||
<a-icon type="logout"></a-icon>
|
||||
<span>
|
||||
<b>{{ i18n "menu.logout"}}</b>
|
||||
</span>
|
||||
<span>{{ i18n "menu.logout"}}</span>
|
||||
</a-menu-item>
|
||||
{{end}}
|
||||
|
||||
|
|
55
web/html/xui/component/aCustomStatistic.html
Normal file
55
web/html/xui/component/aCustomStatistic.html
Normal file
|
@ -0,0 +1,55 @@
|
|||
{{define "component/customStatistic"}}
|
||||
<template>
|
||||
<a-statistic :title="title" :value="value">
|
||||
<template #prefix>
|
||||
<slot name="prefix"></slot>
|
||||
</template>
|
||||
<template #suffix>
|
||||
<slot name="suffix"></slot>
|
||||
</template>
|
||||
</a-statistic>
|
||||
</template>
|
||||
{{end}}
|
||||
|
||||
{{define "component/aCustomStatistic"}}
|
||||
<style>
|
||||
.dark .ant-statistic-title,
|
||||
.dark .ant-statistic-content {
|
||||
color: var(--dark-color-text-primary) !important
|
||||
}
|
||||
|
||||
.dark .ant-statistic-title {
|
||||
user-select: none;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.ant-statistic-title {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.ant-statistic-content-prefix {
|
||||
margin-right: 6px !important;
|
||||
}
|
||||
|
||||
.ant-statistic-content-prefix,
|
||||
.ant-statistic-content-value {
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
Vue.component('a-custom-statistic', {
|
||||
props: {
|
||||
'title': {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
'value': {
|
||||
type: String,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
template: `{{template "component/customStatistic"}}`,
|
||||
});
|
||||
</script>
|
||||
{{end}}
|
|
@ -12,7 +12,7 @@
|
|||
</template>
|
||||
{{end}}
|
||||
|
||||
{{define "component/password"}}
|
||||
{{define "component/aPasswordInput"}}
|
||||
<script>
|
||||
Vue.component('a-password-input', {
|
||||
props: {
|
|
@ -12,7 +12,7 @@
|
|||
</template>
|
||||
{{end}}
|
||||
|
||||
{{define "component/persianDatepicker"}}
|
||||
{{define "component/aPersianDatepicker"}}
|
||||
<link rel="stylesheet" href="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.css?{{ .cur_ver }}" />
|
||||
<script src="{{ .base_path }}assets/moment/moment-jalali.min.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.js?{{ .cur_ver }}"></script>
|
|
@ -18,18 +18,10 @@
|
|||
</a-list-item>
|
||||
{{end}}
|
||||
|
||||
{{define "component/setting"}}
|
||||
{{define "component/aSettingListItem"}}
|
||||
<script>
|
||||
Vue.component('a-setting-list-item', {
|
||||
props: {
|
||||
'title': {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
'description': {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
'paddings': {
|
||||
type: String,
|
||||
required: false,
|
|
@ -3,7 +3,7 @@
|
|||
@click="clickHandler" />
|
||||
{{end}}
|
||||
|
||||
{{define "component/sortableTable"}}
|
||||
{{define "component/aTableSortable"}}
|
||||
<script>
|
||||
const DRAGGABLE_ROW_CLASS = 'draggable-row';
|
||||
const findParentRowElement = (el) => {
|
|
@ -4,15 +4,15 @@
|
|||
<a-sub-menu>
|
||||
<span slot="title">
|
||||
<a-icon type="bulb" :theme="themeSwitcher.isDarkTheme ? 'filled' : 'outlined'"></a-icon>
|
||||
<span>Theme</span>
|
||||
<span>{{ i18n "menu.theme" }}</span>
|
||||
</span>
|
||||
<a-menu-item id="change-theme" class="ant-menu-theme-switch" @mousedown="themeSwitcher.animationsOff()"> Dark
|
||||
<a-switch style="margin-left: 2px;" size="small" :default-checked="themeSwitcher.isDarkTheme"
|
||||
@change="themeSwitcher.toggleTheme()"></a-switch>
|
||||
<a-menu-item id="change-theme" class="ant-menu-theme-switch" @mousedown="themeSwitcher.animationsOff()">
|
||||
<span>{{ i18n "menu.dark" }}</span>
|
||||
<a-switch style="margin-left: 2px;" size="small" :default-checked="themeSwitcher.isDarkTheme" @change="themeSwitcher.toggleTheme()"></a-switch>
|
||||
</a-menu-item>
|
||||
<a-menu-item id="change-theme-ultra" v-if="themeSwitcher.isDarkTheme" class="ant-menu-theme-switch"
|
||||
@mousedown="themeSwitcher.animationsOffUltra()"> Ultra <a-checkbox style="margin-left: 2px;"
|
||||
:checked="themeSwitcher.isUltra" @click="themeSwitcher.toggleUltra()"></a-checkbox>
|
||||
<a-menu-item id="change-theme-ultra" v-if="themeSwitcher.isDarkTheme" class="ant-menu-theme-switch" @mousedown="themeSwitcher.animationsOffUltra()">
|
||||
<span>{{ i18n "menu.ultraDark" }}</span>
|
||||
<a-checkbox style="margin-left: 2px;" :checked="themeSwitcher.isUltra" @click="themeSwitcher.toggleUltra()"></a-checkbox>
|
||||
</a-menu-item>
|
||||
</a-sub-menu>
|
||||
</a-menu>
|
||||
|
@ -36,7 +36,7 @@
|
|||
</template>
|
||||
{{end}}
|
||||
|
||||
{{define "component/themeSwitcher"}}
|
||||
{{define "component/aThemeSwitch"}}
|
||||
<script>
|
||||
function createThemeSwitcher() {
|
||||
const isDarkTheme = localStorage.getItem('dark-mode') === 'true';
|
|
@ -548,8 +548,8 @@
|
|||
<script src="{{ .base_path }}assets/uri/URI.min.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/js/model/inbound.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/js/model/dbinbound.js?{{ .cur_ver }}"></script>
|
||||
{{template "component/themeSwitcher" .}}
|
||||
{{template "component/persianDatepicker" .}}
|
||||
{{template "component/aThemeSwitch" .}}
|
||||
{{template "component/aPersianDatepicker" .}}
|
||||
<script>
|
||||
const columns = [{
|
||||
title: "ID",
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
.dark .ant-backup-list-item svg,
|
||||
.dark .ant-card-actions>li>*,
|
||||
.dark .ant-badge-status-text,
|
||||
.dark .ant-statistic-title,
|
||||
.dark .ant-statistic-content,
|
||||
.dark .ant-card-extra {
|
||||
color: var(--dark-color-text-primary) !important;
|
||||
}
|
||||
|
@ -44,12 +42,6 @@
|
|||
.ant-card-actions {
|
||||
background: transparent !important;
|
||||
}
|
||||
.ant-statistic-content-prefix {
|
||||
font-size: 20px;
|
||||
}
|
||||
.ant-statistic-content-value {
|
||||
font-size: 18px;
|
||||
}
|
||||
.ip-hidden {
|
||||
filter: blur(10px);
|
||||
}
|
||||
|
@ -123,14 +115,22 @@
|
|||
</transition>
|
||||
<transition name="list" appear>
|
||||
<template v-if="!status.isLoaded">
|
||||
<a-card hoverable style="text-align: center; padding: 30px 0; margin-top: 10px;">
|
||||
<div style="text-align: center; padding: 30px 0; margin-top: 10px;">
|
||||
<a-spin size="large"></a-spin>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-row>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card title='{{ i18n "pages.index.xrayStatus" }}' hoverable>
|
||||
<a-card hoverable>
|
||||
<template #title>
|
||||
<a-space direction="horizontal">
|
||||
<span>{{ i18n "pages.index.xrayStatus" }}</span>
|
||||
<a-tag v-if="isMobile && status.xray.version != 'Unknown'" color="green">
|
||||
v[[ status.xray.version ]]
|
||||
</a-tag>
|
||||
</a-space>
|
||||
</template>
|
||||
<template #extra>
|
||||
<template v-if="status.xray.state != State.Error">
|
||||
<a-badge :text="status.xray.state" :color="status.xray.color" style="text-transform: capitalize;"/>
|
||||
|
@ -150,15 +150,17 @@
|
|||
<template #actions>
|
||||
<a-space direction="horizontal" @click="stopXrayService" style="justify-content: center;">
|
||||
<a-icon type="poweroff"></a-icon>
|
||||
<span>{{ i18n "pages.index.stopXray" }}</span>
|
||||
<span v-if="!isMobile">{{ i18n "pages.index.stopXray" }}</span>
|
||||
</a-space>
|
||||
<a-space direction="horizontal" @click="restartXrayService" style="justify-content: center;">
|
||||
<a-icon type="reload"></a-icon>
|
||||
<span>{{ i18n "pages.index.restartXray" }}</span>
|
||||
<span v-if="!isMobile">{{ i18n "pages.index.restartXray" }}</span>
|
||||
</a-space>
|
||||
<a-space direction="horizontal" @click="openSelectV2rayVersion" style="justify-content: center;">
|
||||
<a-icon type="tool"></a-icon>
|
||||
<span>v[[ status.xray.version ]]</span>
|
||||
<span v-if="!isMobile">
|
||||
[[ status.xray.version != 'Unknown' ? `v${status.xray.version}` : '{{ i18n "pages.index.xraySwitch" }}' ]]
|
||||
</span>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-card>
|
||||
|
@ -168,15 +170,15 @@
|
|||
<template #actions>
|
||||
<a-space direction="horizontal" @click="openLogs()" style="justify-content: center;">
|
||||
<a-icon type="bars"></a-icon>
|
||||
<span>{{ i18n "pages.index.logs" }}</span>
|
||||
<span v-if="!isMobile">{{ i18n "pages.index.logs" }}</span>
|
||||
</a-space>
|
||||
<a-space direction="horizontal" @click="openConfig" style="justify-content: center;">
|
||||
<a-icon type="control"></a-icon>
|
||||
<span>{{ i18n "pages.index.config" }}</span>
|
||||
<span v-if="!isMobile">{{ i18n "pages.index.config" }}</span>
|
||||
</a-space>
|
||||
<a-space direction="horizontal" @click="openBackup" style="justify-content: center;">
|
||||
<a-icon type="cloud-server"></a-icon>
|
||||
<span>{{ i18n "pages.index.backup" }}</span>
|
||||
<span v-if="!isMobile">{{ i18n "pages.index.backup" }}</span>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-card>
|
||||
|
@ -223,18 +225,18 @@
|
|||
</template>
|
||||
<a-row :class="showIp ? 'ip-visible' : 'ip-hidden'">
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title="IPv4" :value="status.publicIP.ipv4">
|
||||
<a-custom-statistic title="IPv4" :value="status.publicIP.ipv4">
|
||||
<template #prefix>
|
||||
<a-icon type="global" />
|
||||
</template>
|
||||
</a-statistic>
|
||||
</a-custom-statistic>
|
||||
</a-col>
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title="IPv6" :value="status.publicIP.ipv6">
|
||||
<a-custom-statistic title="IPv6" :value="status.publicIP.ipv6">
|
||||
<template #prefix>
|
||||
<a-icon type="global" />
|
||||
</template>
|
||||
</a-statistic>
|
||||
</a-custom-statistic>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
|
@ -243,18 +245,18 @@
|
|||
<a-card title='{{ i18n "pages.index.connectionCount" }}' hoverable>
|
||||
<a-row>
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title="TCP" :value="status.tcpCount">
|
||||
<a-custom-statistic title="TCP" :value="status.tcpCount">
|
||||
<template #prefix>
|
||||
<a-icon type="swap" />
|
||||
</template>
|
||||
</a-statistic>
|
||||
</a-custom-statistic>
|
||||
</a-col>
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title="UDP" :value="status.udpCount">
|
||||
<a-custom-statistic title="UDP" :value="status.udpCount">
|
||||
<template #prefix>
|
||||
<a-icon type="swap" />
|
||||
</template>
|
||||
</a-statistic>
|
||||
</a-custom-statistic>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
|
@ -263,24 +265,24 @@
|
|||
<a-card title='{{ i18n "pages.index.overallSpeed" }}' hoverable>
|
||||
<a-row>
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title='{{ i18n "pages.index.upload" }}' :value="SizeFormatter.sizeFormat(status.netIO.up)">
|
||||
<a-custom-statistic title='{{ i18n "pages.index.upload" }}' :value="SizeFormatter.sizeFormat(status.netIO.up)">
|
||||
<template #prefix>
|
||||
<a-icon type="arrow-up" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
/s
|
||||
</template>
|
||||
</a-statistic>
|
||||
</a-custom-statistic>
|
||||
</a-col>
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title='{{ i18n "pages.index.download" }}' :value="SizeFormatter.sizeFormat(status.netIO.down)">
|
||||
<a-custom-statistic title='{{ i18n "pages.index.download" }}' :value="SizeFormatter.sizeFormat(status.netIO.down)">
|
||||
<template #prefix>
|
||||
<a-icon type="arrow-down" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
/s
|
||||
</template>
|
||||
</a-statistic>
|
||||
</a-custom-statistic>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
|
@ -289,18 +291,18 @@
|
|||
<a-card title='{{ i18n "pages.index.totalData" }}' hoverable>
|
||||
<a-row>
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title='{{ i18n "pages.index.sent" }}' :value="SizeFormatter.sizeFormat(status.netTraffic.sent)">
|
||||
<a-custom-statistic title='{{ i18n "pages.index.sent" }}' :value="SizeFormatter.sizeFormat(status.netTraffic.sent)">
|
||||
<template #prefix>
|
||||
<a-icon type="cloud-upload" />
|
||||
</template>
|
||||
</a-statistic>
|
||||
</a-custom-statistic>
|
||||
</a-col>
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title='{{ i18n "pages.index.received" }}' :value="SizeFormatter.sizeFormat(status.netTraffic.recv)">
|
||||
<a-custom-statistic title='{{ i18n "pages.index.received" }}' :value="SizeFormatter.sizeFormat(status.netTraffic.recv)">
|
||||
<template #prefix>
|
||||
<a-icon type="cloud-download" />
|
||||
</template>
|
||||
</a-statistic>
|
||||
</a-custom-statistic>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
|
@ -397,7 +399,8 @@
|
|||
</a-modal>
|
||||
</a-layout>
|
||||
{{template "js" .}}
|
||||
{{template "component/themeSwitcher" .}}
|
||||
{{template "component/aThemeSwitch" .}}
|
||||
{{template "component/aCustomStatistic" .}}
|
||||
{{template "textModal"}}
|
||||
<script>
|
||||
const State = {
|
||||
|
|
|
@ -663,9 +663,9 @@
|
|||
</a-layout>
|
||||
{{template "js" .}}
|
||||
<script src="{{ .base_path }}assets/js/model/setting.js?{{ .cur_ver }}"></script>
|
||||
{{template "component/themeSwitcher" .}}
|
||||
{{template "component/password" .}}
|
||||
{{template "component/setting"}}
|
||||
{{template "component/aThemeSwitch" .}}
|
||||
{{template "component/aPasswordInput" .}}
|
||||
{{template "component/aSettingListItem" .}}
|
||||
<script>
|
||||
const app = new Vue({
|
||||
delimiters: ['[[', ']]'],
|
||||
|
|
|
@ -788,9 +788,9 @@
|
|||
</a-layout>
|
||||
</a-layout>
|
||||
{{template "js" .}}
|
||||
{{template "component/themeSwitcher" .}}
|
||||
{{template "component/sortableTable" .}}
|
||||
{{template "component/setting"}}
|
||||
{{template "component/aThemeSwitch" .}}
|
||||
{{template "component/aTableSortable" .}}
|
||||
{{template "component/aSettingListItem" .}}
|
||||
{{template "ruleModal"}}
|
||||
{{template "outModal"}}
|
||||
{{template "reverseModal"}}
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "No added reverse proxies."
|
||||
|
||||
[menu]
|
||||
"theme" = "Theme"
|
||||
"dark" = "Dark"
|
||||
"ultraDark" = "Ultra Dark"
|
||||
"dashboard" = "Overview"
|
||||
"inbounds" = "Inbounds"
|
||||
"settings" = "Panel Settings"
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "No hay proxies inversos añadidos."
|
||||
|
||||
[menu]
|
||||
"theme" = "Tema"
|
||||
"dark" = "Oscuro"
|
||||
"ultraDark" = "Ultra Oscuro"
|
||||
"dashboard" = "Estado del Sistema"
|
||||
"inbounds" = "Entradas"
|
||||
"settings" = "Configuraciones"
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "هیچ پروکسی معکوس اضافه نشده است."
|
||||
|
||||
[menu]
|
||||
"theme" = "تم"
|
||||
"dark" = "تیره"
|
||||
"ultraDark" = "فوق تیره"
|
||||
"dashboard" = "نمای کلی"
|
||||
"inbounds" = "ورودیها"
|
||||
"settings" = "تنظیمات پنل"
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "Tidak ada proxy terbalik yang ditambahkan."
|
||||
|
||||
[menu]
|
||||
"theme" = "Tema"
|
||||
"dark" = "Gelap"
|
||||
"ultraDark" = "Sangat Gelap"
|
||||
"dashboard" = "Ikhtisar"
|
||||
"inbounds" = "Masuk"
|
||||
"settings" = "Pengaturan Panel"
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "追加されたリバースプロキシはありません。"
|
||||
|
||||
[menu]
|
||||
"theme" = "テーマ"
|
||||
"dark" = "ダーク"
|
||||
"ultraDark" = "ウルトラダーク"
|
||||
"dashboard" = "ダッシュボード"
|
||||
"inbounds" = "インバウンド一覧"
|
||||
"settings" = "パネル設定"
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "Nenhum proxy reverso adicionado."
|
||||
|
||||
[menu]
|
||||
"theme" = "Tema"
|
||||
"dark" = "Escuro"
|
||||
"ultraDark" = "Ultra Escuro"
|
||||
"dashboard" = "Visão Geral"
|
||||
"inbounds" = "Inbounds"
|
||||
"settings" = "Panel Settings"
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "Нет добавленных обратных прокси."
|
||||
|
||||
[menu]
|
||||
"theme" = "Тема"
|
||||
"dark" = "Темная"
|
||||
"ultraDark" = "Ультра темная"
|
||||
"dashboard" = "Статус системы"
|
||||
"inbounds" = "Подключения"
|
||||
"settings" = "Настройки панели"
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "Eklenmiş ters proxy yok."
|
||||
|
||||
[menu]
|
||||
"theme" = "Tema"
|
||||
"dark" = "Koyu"
|
||||
"ultraDark" = "Ultra Koyu"
|
||||
"dashboard" = "Genel Bakış"
|
||||
"inbounds" = "Gelenler"
|
||||
"settings" = "Panel Ayarları"
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "Немає доданих зворотних проксі."
|
||||
|
||||
[menu]
|
||||
"theme" = "Тема"
|
||||
"dark" = "Темна"
|
||||
"ultraDark" = "Ультра темна"
|
||||
"dashboard" = "Огляд"
|
||||
"inbounds" = "Вхідні"
|
||||
"settings" = "Параметри панелі"
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "Không có proxy ngược nào được thêm."
|
||||
|
||||
[menu]
|
||||
"theme" = "Chủ đề"
|
||||
"dark" = "Tối"
|
||||
"ultraDark" = "Siêu tối"
|
||||
"dashboard" = "Trạng thái hệ thống"
|
||||
"inbounds" = "Đầu vào khách hàng"
|
||||
"settings" = "Cài đặt bảng điều khiển"
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "未添加反向代理。"
|
||||
|
||||
[menu]
|
||||
"theme" = "主题"
|
||||
"dark" = "暗色"
|
||||
"ultraDark" = "超暗色"
|
||||
"dashboard" = "系统状态"
|
||||
"inbounds" = "入站列表"
|
||||
"settings" = "面板设置"
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
"emptyReverseDesc" = "未添加反向代理。"
|
||||
|
||||
[menu]
|
||||
"theme" = "主題"
|
||||
"dark" = "深色"
|
||||
"ultraDark" = "超深色"
|
||||
"dashboard" = "系統狀態"
|
||||
"inbounds" = "入站列表"
|
||||
"settings" = "面板設定"
|
||||
|
|
Loading…
Reference in a new issue