added datepicker option in setting page

jalalian datepicker component was added
translate files for datepicker updated
This commit is contained in:
ali rahimi 2023-12-26 15:34:16 +01:00
parent bbcab768ca
commit fe36d066ee
25 changed files with 1482 additions and 149 deletions

View file

@ -20,6 +20,7 @@ type SubService struct {
address string address string
showInfo bool showInfo bool
remarkModel string remarkModel string
datepicker string
inboundService service.InboundService inboundService service.InboundService
settingService service.SettingService settingService service.SettingService
} }
@ -39,6 +40,10 @@ func (s *SubService) GetSubs(subId string, host string, showInfo bool) ([]string
if err != nil { if err != nil {
s.remarkModel = "-ieo" s.remarkModel = "-ieo"
} }
s.datepicker, err = s.settingService.GetDatepicker()
if err != nil {
s.datepicker = "gregorian"
}
for _, inbound := range inbounds { for _, inbound := range inbounds {
clients, err := s.inboundService.GetClients(inbound) clients, err := s.inboundService.GetClients(inbound)
if err != nil { if err != nil {

View file

@ -12,6 +12,7 @@ class AllSetting {
this.expireDiff = ""; this.expireDiff = "";
this.trafficDiff = ""; this.trafficDiff = "";
this.remarkModel = "-ieo"; this.remarkModel = "-ieo";
this.datepicker = "gregorian";
this.tgBotEnable = false; this.tgBotEnable = false;
this.tgBotToken = ""; this.tgBotToken = "";
this.tgBotChatId = ""; this.tgBotChatId = "";

1252
web/assets/moment/moment-jalali.min.js vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -47,6 +47,7 @@ type AllSetting struct {
SubEncrypt bool `json:"subEncrypt" form:"subEncrypt"` SubEncrypt bool `json:"subEncrypt" form:"subEncrypt"`
SubShowInfo bool `json:"subShowInfo" form:"subShowInfo"` SubShowInfo bool `json:"subShowInfo" form:"subShowInfo"`
SubURI string `json:"subURI" form:"subURI"` SubURI string `json:"subURI" form:"subURI"`
Datepicker string `json:"datepicker" form:"datepicker"`
} }
func (s *AllSetting) CheckValid() error { func (s *AllSetting) CheckValid() error {

View file

@ -104,8 +104,10 @@
<a-icon type="question-circle"></a-icon> <a-icon type="question-circle"></a-icon>
</a-tooltip> </a-tooltip>
</template> </template>
<a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss" <a-date-picker v-if="datepicker == 'gregorian'" :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
:dropdown-class-name="themeSwitcher.currentTheme" v-model="clientsBulkModal.expiryTime"></a-date-picker> :dropdown-class-name="themeSwitcher.currentTheme" v-model="clientsBulkModal.expiryTime"></a-date-picker>
<persian-datepicker v-else :dropdown-class-name="themeSwitcher.currentTheme"
value="clientsBulkModal.expiryTime" v-model="clientsBulkModal.expiryTime"></persian-datepicker>
</a-form-item> </a-form-item>
<a-form-item v-if="clientsBulkModal.expiryTime != 0"> <a-form-item v-if="clientsBulkModal.expiryTime != 0">
<template slot="label"> <template slot="label">
@ -234,6 +236,9 @@
get delayedExpireDays() { get delayedExpireDays() {
return this.clientsBulkModal.expiryTime < 0 ? this.clientsBulkModal.expiryTime / -86400000 : 0; return this.clientsBulkModal.expiryTime < 0 ? this.clientsBulkModal.expiryTime / -86400000 : 0;
}, },
get datepicker() {
return app.datepicker;
},
set delayedExpireDays(days) { set delayedExpireDays(days) {
this.clientsBulkModal.expiryTime = -86400000 * days; this.clientsBulkModal.expiryTime = -86400000 * days;
}, },

View file

@ -94,6 +94,9 @@
get isEdit() { get isEdit() {
return this.clientModal.isEdit; return this.clientModal.isEdit;
}, },
get datepicker() {
return app.datepicker;
},
get isTrafficExhausted() { get isTrafficExhausted() {
if (!clientStats) return false if (!clientStats) return false
if (clientStats.total <= 0) return false if (clientStats.total <= 0) return false

View file

@ -0,0 +1,59 @@
{{define "component/persianDatepickerTemplate"}}
<template>
<div>
<a-input :value="value" type="text" v-model="date" data-jdp class="persian-datepicker"
@input="$emit('input', convertToGregorian($event.target.value)); jalaliDatepicker.hide();"
placeholder="انتخاب تاریخ">
<template #addonAfter>
<a-icon type="calendar" style="font-size: 16px;"/>
</template>
</a-input>
</div>
</template>
{{end}}
{{define "component/persianDatepicker"}}
<link rel="stylesheet" href="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.css"/>
<script src="{{ .base_path }}assets/moment/moment-jalali.min.js"></script>
<script src="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.js"></script>
<script>
const persianDatepicker = {};
Vue.component('persian-datepicker', {
props: ['dropdown-class-name', 'format', 'value'],
template: `{{template "component/persianDatepickerTemplate"}}`,
data() {
return {
date: '',
persianDatepicker,
};
},
watch: {
value: function (date) {
this.date = this.convertToJalalian(date)
}
},
mounted() {
this.date = this.convertToJalalian(this.value)
this.listenToDatepicker()
},
methods: {
convertToGregorian(date) {
return date ? moment(moment(date, 'jYYYY/jMM/jDD HH:mm:ss').format('YYYY-MM-DD HH:mm:ss')) : null
},
convertToJalalian(date) {
return date && moment.isMoment(date) ? date.format('jYYYY/jMM/jDD HH:mm:ss') : null
},
listenToDatepicker() {
jalaliDatepicker.startWatch({
time: true,
hideAfterChange: true,
useDropDownYears: false,
changeMonthRotateYear: true,
});
},
}
});
</script>
{{end}}

View file

@ -150,8 +150,10 @@
<a-icon type="question-circle"></a-icon> <a-icon type="question-circle"></a-icon>
</a-tooltip> </a-tooltip>
</template> </template>
<a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss" <a-date-picker v-if="datepicker == 'gregorian'" :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
:dropdown-class-name="themeSwitcher.currentTheme" v-model="client._expiryTime"></a-date-picker> :dropdown-class-name="themeSwitcher.currentTheme" v-model="client._expiryTime"></a-date-picker>
<persian-datepicker v-else :dropdown-class-name="themeSwitcher.currentTheme"
value="client._expiryTime" v-model="client._expiryTime"></persian-datepicker>
<a-tag color="red" v-if="isEdit && isExpiry">Expired</a-tag> <a-tag color="red" v-if="isEdit && isExpiry">Expired</a-tag>
</a-form-item> </a-form-item>
<a-form-item v-if="client.expiryTime != 0"> <a-form-item v-if="client.expiryTime != 0">

View file

@ -54,9 +54,11 @@
<a-icon type="question-circle"></a-icon> <a-icon type="question-circle"></a-icon>
</a-tooltip> </a-tooltip>
</template> </template>
<a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss" <a-date-picker v-if="datepicker == 'gregorian'" :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
:dropdown-class-name="themeSwitcher.currentTheme" :dropdown-class-name="themeSwitcher.currentTheme"
v-model="dbInbound._expiryTime"></a-date-picker> v-model="dbInbound._expiryTime"></a-date-picker>
<persian-datepicker v-else :dropdown-class-name="themeSwitcher.currentTheme"
value="dbInbound._expiryTime" v-model="dbInbound._expiryTime"></persian-datepicker>
</a-form-item> </a-form-item>
</a-form> </a-form>

View file

@ -33,7 +33,7 @@
</template> </template>
</a-form-item> </a-form-item>
<a-form-item label='{{ i18n "pages.inbounds.stream.general.requestHeader" }}'> <a-form-item label='{{ i18n "pages.inbounds.stream.general.requestHeader" }}'>
<a-button size="small" @click="inbound.stream.tcp.request.addHeader('host', '')">+</a-button> <a-button size="small" @click="inbound.stream.tcp.request.addHeader('', '')">+</a-button>
</a-form-item> </a-form-item>
<a-form-item :wrapper-col="{span:24}"> <a-form-item :wrapper-col="{span:24}">
<a-input-group compact v-for="(header, index) in inbound.stream.tcp.request.headers"> <a-input-group compact v-for="(header, index) in inbound.stream.tcp.request.headers">

View file

@ -63,6 +63,9 @@
get client() { get client() {
return inModal.inbound.clients[0]; return inModal.inbound.clients[0];
}, },
get datepicker() {
return app.datepicker;
},
get delayedExpireDays() { get delayedExpireDays() {
return this.client && this.client.expiryTime < 0 ? this.client.expiryTime / -86400000 : 0; return this.client && this.client.expiryTime < 0 ? this.client.expiryTime / -86400000 : 0;
}, },

View file

@ -446,6 +446,7 @@
<script src="{{ .base_path }}assets/js/model/xray.js?{{ .cur_ver }}"></script> <script src="{{ .base_path }}assets/js/model/xray.js?{{ .cur_ver }}"></script>
<script src="{{ .base_path }}assets/js/model/dbinbound.js?{{ .cur_ver }}"></script> <script src="{{ .base_path }}assets/js/model/dbinbound.js?{{ .cur_ver }}"></script>
{{template "component/themeSwitcher" .}} {{template "component/themeSwitcher" .}}
{{template "component/persianDatepicker" .}}
<script> <script>
const columns = [{ const columns = [{
title: "ID", title: "ID",
@ -539,6 +540,7 @@
data: { data: {
siderDrawer, siderDrawer,
themeSwitcher, themeSwitcher,
persianDatepicker,
spinning: false, spinning: false,
inbounds: [], inbounds: [],
dbInbounds: [], dbInbounds: [],
@ -560,6 +562,7 @@
subURI : '' subURI : ''
}, },
remarkModel: '-ieo', remarkModel: '-ieo',
datepicker: 'gregorian',
tgBotEnable: false, tgBotEnable: false,
pageSize: 0, pageSize: 0,
isMobile: window.innerWidth <= 768, isMobile: window.innerWidth <= 768,
@ -605,6 +608,7 @@
}; };
this.pageSize = pageSize; this.pageSize = pageSize;
this.remarkModel = remarkModel; this.remarkModel = remarkModel;
this.datepicker = datepicker;
} }
}, },
setInbounds(dbInbounds) { setInbounds(dbInbounds) {

View file

@ -138,6 +138,27 @@
<setting-list-item type="number" title='{{ i18n "pages.settings.expireTimeDiff" }}' desc='{{ i18n "pages.settings.expireTimeDiffDesc" }}' v-model="allSetting.expireDiff" :min="0"></setting-list-item> <setting-list-item type="number" title='{{ i18n "pages.settings.expireTimeDiff" }}' desc='{{ i18n "pages.settings.expireTimeDiffDesc" }}' v-model="allSetting.expireDiff" :min="0"></setting-list-item>
<setting-list-item type="number" title='{{ i18n "pages.settings.trafficDiff" }}' desc='{{ i18n "pages.settings.trafficDiffDesc" }}' v-model="allSetting.trafficDiff" :min="0"></setting-list-item> <setting-list-item type="number" title='{{ i18n "pages.settings.trafficDiff" }}' desc='{{ i18n "pages.settings.trafficDiffDesc" }}' v-model="allSetting.trafficDiff" :min="0"></setting-list-item>
<setting-list-item type="text" title='{{ i18n "pages.settings.timeZone"}}' desc='{{ i18n "pages.settings.timeZoneDesc"}}' v-model="allSetting.timeLocation"></setting-list-item> <setting-list-item type="text" title='{{ i18n "pages.settings.timeZone"}}' desc='{{ i18n "pages.settings.timeZoneDesc"}}' v-model="allSetting.timeLocation"></setting-list-item>
<a-list-item>
<a-row style="padding: 20px">
<a-col :lg="24" :xl="12">
<a-list-item-meta title='{{ i18n "pages.settings.datepicker"}}'>
<template slot="description">{{ i18n "pages.settings.datepickerDescription"}}</template>
</a-list-item-meta>
</a-col>
<a-col :lg="24" :xl="12">
<template>
<a-select style="width: 100%"
:dropdown-class-name="themeSwitcher.currentTheme"
v-model="datepicker">
<a-select-option v-for="item in datepickerList" :value="item.value">
<span v-text="item.name"></span>
</a-select-option>
</a-select>
</template>
</a-col>
</a-row>
</a-list-item>
<a-list-item> <a-list-item>
<a-row style="padding: 20px"> <a-row style="padding: 20px">
<a-col :lg="24" :xl="12"> <a-col :lg="24" :xl="12">
@ -197,7 +218,7 @@
<td> <td>
<a-form-item> <a-form-item>
<password-input v-model="user.newPassword" style="width: 200px"></password-input> <password-input v-model="user.newPassword" style="width: 200px"></password-input>
</a-form-item> </a-form-item>
</td> </td>
</tr> </tr>
</table> </table>
@ -311,6 +332,7 @@
showAlert: false, showAlert: false,
remarkModels: {i:'Inbound',e:'Email',o:'Other'}, remarkModels: {i:'Inbound',e:'Email',o:'Other'},
remarkSeparators: [' ','-','_','@',':','~','|',',','.','/'], remarkSeparators: [' ','-','_','@',':','~','|',',','.','/'],
datepickerList: [{name:'Gregorian (Standard)', value: 'gregorian'}, {name:'Jalalian (شمسی)', value: 'jalalian'}],
remarkSample: '', remarkSample: '',
get remarkModel() { get remarkModel() {
rm = this.allSetting.remarkModel; rm = this.allSetting.remarkModel;
@ -328,11 +350,17 @@
this.allSetting.remarkModel = value + this.allSetting.remarkModel.substring(1); this.allSetting.remarkModel = value + this.allSetting.remarkModel.substring(1);
this.changeRemarkSample(); this.changeRemarkSample();
}, },
get datepicker() {
return this.allSetting.datepicker ? this.allSetting.datepicker : 'gregorian';
},
set datepicker(value) {
this.allSetting.datepicker = value;
},
changeRemarkSample(){ changeRemarkSample(){
sample = [] sample = []
this.remarkModel.forEach(r => sample.push(this.remarkModels[r])); this.remarkModel.forEach(r => sample.push(this.remarkModels[r]));
this.remarkSample = sample.length == 0 ? '' : sample.join(this.remarkSeparator); this.remarkSample = sample.length == 0 ? '' : sample.join(this.remarkSeparator);
} }
}, },
methods: { methods: {
loading(spinning = true) { loading(spinning = true) {
@ -384,7 +412,9 @@
if (msg.success) { if (msg.success) {
this.loading(true); this.loading(true);
await PromiseUtil.sleep(5000); await PromiseUtil.sleep(5000);
let { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.allSetting; var { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.allSetting;
if (host == this.oldAllSetting.webDomain) host = null;
if (port == this.oldAllSetting.webPort) port = null;
const isTLS = webCertFile !== "" || webKeyFile !== ""; const isTLS = webCertFile !== "" || webKeyFile !== "";
const url = buildURL({ host, port, isTLS, base, path: "panel/settings" }); const url = buildURL({ host, port, isTLS, base, path: "panel/settings" });
window.location.replace(url); window.location.replace(url);

View file

@ -157,7 +157,6 @@
<setting-list-item type="switch" title='{{ i18n "pages.xray.PrivateIp"}}' desc='{{ i18n "pages.xray.PrivateIpDesc"}}' v-model="privateIpSettings"></setting-list-item> <setting-list-item type="switch" title='{{ i18n "pages.xray.PrivateIp"}}' desc='{{ i18n "pages.xray.PrivateIpDesc"}}' v-model="privateIpSettings"></setting-list-item>
<setting-list-item type="switch" title='{{ i18n "pages.xray.Ads"}}' desc='{{ i18n "pages.xray.AdsDesc"}}' v-model="AdsSettings"></setting-list-item> <setting-list-item type="switch" title='{{ i18n "pages.xray.Ads"}}' desc='{{ i18n "pages.xray.AdsDesc"}}' v-model="AdsSettings"></setting-list-item>
<setting-list-item type="switch" title='{{ i18n "pages.xray.Family"}}' desc='{{ i18n "pages.xray.FamilyDesc"}}' v-model="familyProtectSettings"></setting-list-item> <setting-list-item type="switch" title='{{ i18n "pages.xray.Family"}}' desc='{{ i18n "pages.xray.FamilyDesc"}}' v-model="familyProtectSettings"></setting-list-item>
<setting-list-item type="switch" title='{{ i18n "pages.xray.Security"}}' desc='{{ i18n "pages.xray.SecurityDesc"}}' v-model="SecuritySettings"></setting-list-item>
<setting-list-item type="switch" title='{{ i18n "pages.xray.Speedtest"}}' desc='{{ i18n "pages.xray.SpeedtestDesc"}}' v-model="SpeedTestSettings"></setting-list-item> <setting-list-item type="switch" title='{{ i18n "pages.xray.Speedtest"}}' desc='{{ i18n "pages.xray.SpeedtestDesc"}}' v-model="SpeedTestSettings"></setting-list-item>
</a-collapse-panel> </a-collapse-panel>
<a-collapse-panel header='{{ i18n "pages.xray.blockCountryConfigs"}}'> <a-collapse-panel header='{{ i18n "pages.xray.blockCountryConfigs"}}'>
@ -545,11 +544,6 @@
"geosite:category-ads-all", "geosite:category-ads-all",
"ext:geosite_IR.dat:category-ads-all" "ext:geosite_IR.dat:category-ads-all"
], ],
security: [
"ext:geosite_IR.dat:malware",
"ext:geosite_IR.dat:phishing",
"ext:geosite_IR.dat:cryptominers"
],
speedtest: ["geosite:speedtest"], speedtest: ["geosite:speedtest"],
openai: ["geosite:openai"], openai: ["geosite:openai"],
google: ["geosite:google"], google: ["geosite:google"],
@ -566,7 +560,7 @@
ir: [ ir: [
"regexp:.*\\.ir$", "regexp:.*\\.ir$",
"regexp:.*\\.xn--mgba3a4f16a$", // .ایران "regexp:.*\\.xn--mgba3a4f16a$", // .ایران
"ext:geosite_IR.dat:ir" "ext:geosite_IR.dat:ir" // have rules to bypass all .ir domains.
], ],
vn: [ vn: [
"regexp:.*\\.vn$", "regexp:.*\\.vn$",
@ -577,7 +571,9 @@
familyProtectDNS: { familyProtectDNS: {
"servers": [ "servers": [
"1.1.1.3", // https://developers.cloudflare.com/1.1.1.1/setup/ "1.1.1.3", // https://developers.cloudflare.com/1.1.1.1/setup/
"1.0.0.3" "1.0.0.3",
"94.140.14.15", // https://adguard-dns.io/kb/general/dns-providers/
"94.140.15.16"
], ],
"queryStrategy": "UseIPv4" "queryStrategy": "UseIPv4"
}, },
@ -1186,18 +1182,6 @@
} }
}, },
}, },
SecuritySettings: {
get: function () {
return doAllItemsExist(this.settingsData.domains.security, this.blockedDomains);
},
set: function (newValue) {
if (newValue) {
this.blockedDomains = [...this.blockedDomains, ...this.settingsData.domains.security];
} else {
this.blockedDomains = this.blockedDomains.filter(data => !this.settingsData.domains.security.includes(data));
}
},
},
SpeedTestSettings: { SpeedTestSettings: {
get: function () { get: function () {
return doAllItemsExist(this.settingsData.domains.speedtest, this.blockedDomains); return doAllItemsExist(this.settingsData.domains.speedtest, this.blockedDomains);

View file

@ -36,8 +36,8 @@
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item label='Protocol'> <a-form-item label='Protocol'>
<a-select v-model="ruleModal.rule.protocol" mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme"> <a-select v-model="ruleModal.rule.protocol" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="x in ['http','tls','bittorrent']" :value="x">[[ x ]]</a-select-option> <a-select-option v-for="x in ['','http','tls','bittorrent']" :value="x">[[ x ]]</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item label='Attributes'> <a-form-item label='Attributes'>

View file

@ -56,6 +56,7 @@ var defaultValueMap = map[string]string{
"subEncrypt": "true", "subEncrypt": "true",
"subShowInfo": "true", "subShowInfo": "true",
"subURI": "", "subURI": "",
"datepicker": "gregorian",
} }
type SettingService struct { type SettingService struct {
@ -417,6 +418,10 @@ func (s *SettingService) GetSubURI() (string, error) {
return s.getString("subURI") return s.getString("subURI")
} }
func (s *SettingService) GetDatepicker() (string, error) {
return s.getString("datepicker")
}
func (s *SettingService) GetPageSize() (int, error) { func (s *SettingService) GetPageSize() (int, error) {
return s.getInt("pageSize") return s.getInt("pageSize")
} }
@ -463,6 +468,7 @@ func (s *SettingService) GetDefaultSettings(host string) (interface{}, error) {
"subEnable": func() (interface{}, error) { return s.GetSubEnable() }, "subEnable": func() (interface{}, error) { return s.GetSubEnable() },
"subURI": func() (interface{}, error) { return s.GetSubURI() }, "subURI": func() (interface{}, error) { return s.GetSubURI() },
"remarkModel": func() (interface{}, error) { return s.GetRemarkModel() }, "remarkModel": func() (interface{}, error) { return s.GetRemarkModel() },
"datepicker": func() (interface{}, error) { return s.GetDatepicker() },
} }
result := make(map[string]interface{}) result := make(map[string]interface{})

View file

@ -59,7 +59,7 @@
"settings" = "Panel Settings" "settings" = "Panel Settings"
"xray" = "Xray Settings" "xray" = "Xray Settings"
"logout" = "Logout" "logout" = "Logout"
"link" = "Manage" "link" = "Management"
[pages.login] [pages.login]
"title" = "Login" "title" = "Login"
@ -79,7 +79,7 @@
"xrayStatus" = "Status" "xrayStatus" = "Status"
"stopXray" = "Stop" "stopXray" = "Stop"
"restartXray" = "Restart" "restartXray" = "Restart"
"xraySwitch" = "Version" "xraySwitch" = "SwitchV"
"xraySwitchClick" = "Choose the version you want to switch to." "xraySwitchClick" = "Choose the version you want to switch to."
"xraySwitchClickDesk" = "Choose wisely, as older versions may not be compatible with current configurations." "xraySwitchClickDesk" = "Choose wisely, as older versions may not be compatible with current configurations."
"operationHours" = "Uptime" "operationHours" = "Uptime"
@ -246,6 +246,8 @@
"pageSize" = "Pagination Size" "pageSize" = "Pagination Size"
"pageSizeDesc" = "Define page size for inbounds table. Set 0 to disable" "pageSizeDesc" = "Define page size for inbounds table. Set 0 to disable"
"remarkModel" = "Remark Model and Seperation Charachter" "remarkModel" = "Remark Model and Seperation Charachter"
"datepicker" = "Datepicker"
"datepickerDescription" = "Selector calendar type specifies the expiration date"
"sampleRemark" = "Sample Remark" "sampleRemark" = "Sample Remark"
"oldUsername" = "Current Username" "oldUsername" = "Current Username"
"currentPassword" = "Current Password" "currentPassword" = "Current Password"
@ -327,10 +329,8 @@
"PrivateIpDesc" = "Change the configuration template to avoid connecting to private IP ranges." "PrivateIpDesc" = "Change the configuration template to avoid connecting to private IP ranges."
"Ads" = "Block Ads" "Ads" = "Block Ads"
"AdsDesc" = "Change the configuration template to block ads." "AdsDesc" = "Change the configuration template to block ads."
"Family" = "Block malware and Adult Content" "Family" = "Block Malware and Adult Content"
"FamilyDesc" = "Cloudflare DNS resolvers to block malware and adult content for family protection." "FamilyDesc" = "DNS resolvers to block malware and adult content for family protection."
"Security" = "Block Malware, Phishing and Cryptominers Websites"
"SecurityDesc" = "Change the configuration template for Security protection."
"Speedtest" = "Block Speedtest Websites" "Speedtest" = "Block Speedtest Websites"
"SpeedtestDesc" = "Change the configuration template to avoid connecting to speedtest websites." "SpeedtestDesc" = "Change the configuration template to avoid connecting to speedtest websites."
"IRIp" = "Disable Connection to Iran IPs" "IRIp" = "Disable Connection to Iran IPs"

View file

@ -76,10 +76,10 @@
"title" = "Estado del Sistema" "title" = "Estado del Sistema"
"memory" = "Memoria" "memory" = "Memoria"
"hard" = "Disco Duro" "hard" = "Disco Duro"
"xrayStatus" = "Estado de" "xrayStatus" = "Estado de Xray"
"stopXray" = "Detener" "stopXray" = "Detener Xray"
"restartXray" = "Reiniciar" "restartXray" = "Reiniciar"
"xraySwitch" = "Versión" "xraySwitch" = "Cambiar Versión"
"xraySwitchClick" = "Elige la versión a la que deseas cambiar." "xraySwitchClick" = "Elige la versión a la que deseas cambiar."
"xraySwitchClickDesk" = "Elige sabiamente, ya que las versiones anteriores pueden no ser compatibles con las configuraciones actuales." "xraySwitchClickDesk" = "Elige sabiamente, ya que las versiones anteriores pueden no ser compatibles con las configuraciones actuales."
"operationHours" = "Tiempo de Funcionamiento" "operationHours" = "Tiempo de Funcionamiento"
@ -246,6 +246,8 @@
"pageSize" = "Tamaño de paginación" "pageSize" = "Tamaño de paginación"
"pageSizeDesc" = "Defina el tamaño de página para la tabla de entradas. Establezca 0 para desactivar" "pageSizeDesc" = "Defina el tamaño de página para la tabla de entradas. Establezca 0 para desactivar"
"remarkModel" = "Modelo de observación y carácter de separación" "remarkModel" = "Modelo de observación y carácter de separación"
"datepicker" = "selector de fechas"
"datepickerDescription" = "El tipo de calendario selector especifica la fecha de vencimiento"
"sampleRemark" = "Observación de muestra" "sampleRemark" = "Observación de muestra"
"oldUsername" = "Nombre de Usuario Actual" "oldUsername" = "Nombre de Usuario Actual"
"currentPassword" = "Contraseña Actual" "currentPassword" = "Contraseña Actual"
@ -327,10 +329,8 @@
"PrivateIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP privadas." "PrivateIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP privadas."
"Ads" = "Bloquear Anuncios" "Ads" = "Bloquear Anuncios"
"AdsDesc" = "Cambia la plantilla de configuración para bloquear anuncios." "AdsDesc" = "Cambia la plantilla de configuración para bloquear anuncios."
"Family" = "Bloquee malware y contenido para adultos" "Family" = "Bloquear Malware y Contenido para Adultos"
"FamilyDesc" = "Resolutores de DNS de Cloudflare para bloquear malware y contenido para adultos para protección familiar." "FamilyDesc" = "Resolvedores de DNS para bloquear malware y contenido para adultos para protección familiar."
"Security" = "Bloquee sitios web de malware, phishing y criptomineros"
"SecurityDesc" = "Cambiar la plantilla de configuración para la protección de seguridad."
"Speedtest" = "Bloquear Sitios Web de Pruebas de Velocidad" "Speedtest" = "Bloquear Sitios Web de Pruebas de Velocidad"
"SpeedtestDesc" = "Cambia la plantilla de configuración para evitar la conexión a sitios web de pruebas de velocidad." "SpeedtestDesc" = "Cambia la plantilla de configuración para evitar la conexión a sitios web de pruebas de velocidad."
"IRIp" = "Desactivar Conexión a Rangos de IP de Irán" "IRIp" = "Desactivar Conexión a Rangos de IP de Irán"

View file

@ -79,7 +79,7 @@
"xrayStatus" = "وضعیت" "xrayStatus" = "وضعیت"
"stopXray" = "توقف" "stopXray" = "توقف"
"restartXray" = "شروع مجدد" "restartXray" = "شروع مجدد"
"xraySwitch" = "ورژن" "xraySwitch" = "تغییر ورژن"
"xraySwitchClick" = "ورژن مورد نظر را انتخاب کنید" "xraySwitchClick" = "ورژن مورد نظر را انتخاب کنید"
"xraySwitchClickDesk" = "لطفا با دقت انتخاب کنید ، در صورت انتخاب اشتباه امکان قطعی سیستم وجود دارد " "xraySwitchClickDesk" = "لطفا با دقت انتخاب کنید ، در صورت انتخاب اشتباه امکان قطعی سیستم وجود دارد "
"operationHours" = "آپ تایم سیستم" "operationHours" = "آپ تایم سیستم"
@ -246,6 +246,8 @@
"pageSize" = "اندازه صفحه بندی جدول" "pageSize" = "اندازه صفحه بندی جدول"
"pageSizeDesc" = "اندازه صفحه را برای جدول سرویس ها تعریف کنید. 0: غیرفعال" "pageSizeDesc" = "اندازه صفحه را برای جدول سرویس ها تعریف کنید. 0: غیرفعال"
"remarkModel" = "نام کانفیگ و جداکننده" "remarkModel" = "نام کانفیگ و جداکننده"
"datepicker" = "انتخاب کننده تاریخ"
"datepickerDescription" = "نوع تقویم انتخاب کننده تاریخ انقضا را مشخص میکند "
"sampleRemark" = "نمونه نام" "sampleRemark" = "نمونه نام"
"oldUsername" = "نام کاربری فعلی" "oldUsername" = "نام کاربری فعلی"
"currentPassword" = "رمز عبور فعلی" "currentPassword" = "رمز عبور فعلی"
@ -328,9 +330,7 @@
"Ads" = "مسدود کردن تبلیغات" "Ads" = "مسدود کردن تبلیغات"
"AdsDesc" = "الگوی تنظیمات را برای مسدود کردن تبلیغات تغییر میدهد" "AdsDesc" = "الگوی تنظیمات را برای مسدود کردن تبلیغات تغییر میدهد"
"Family" = "فعال کردن حالت خانواده" "Family" = "فعال کردن حالت خانواده"
"FamilyDesc" = "مسدود کردن محتوای بزرگسالان به کمک دی ان اس کلودفلر برای حالت خانواده " "FamilyDesc" = "برای جلوگیری از ارتباط با وبسایت های ناامن"
"Security" = "مسدود کردن وب‌سایت‌های بدافزار، فیشینگ و کریپتومینرها"
"SecurityDesc" = "الگوی پیکربندی را برای حفاظت از امنیت تغییر دهید"
"Speedtest" = "جلوگیری از اتصال به سایت های تست سرعت" "Speedtest" = "جلوگیری از اتصال به سایت های تست سرعت"
"SpeedtestDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال به سایت های تست سرعت تغییر میدهد" "SpeedtestDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال به سایت های تست سرعت تغییر میدهد"
"IRIp" = "جلوگیری از اتصال آیپی های ایران" "IRIp" = "جلوگیری از اتصال آیپی های ایران"

View file

@ -77,9 +77,9 @@
"memory" = "Память" "memory" = "Память"
"hard" = "Жесткий диск" "hard" = "Жесткий диск"
"xrayStatus" = "Статус" "xrayStatus" = "Статус"
"stopXray" = "Остановить" "stopXray" = "Остановить Xray"
"restartXray" = "Перезапустить" "restartXray" = "Перезапустить Xray"
"xraySwitch" = "Версия" "xraySwitch" = "Переключить версию"
"xraySwitchClick" = "Выберите желаемую версию" "xraySwitchClick" = "Выберите желаемую версию"
"xraySwitchClickDesk" = "Выбирайте внимательно, так как старые версии могут быть несовместимы с текущими конфигурациями" "xraySwitchClickDesk" = "Выбирайте внимательно, так как старые версии могут быть несовместимы с текущими конфигурациями"
"operationHours" = "Время работы системы" "operationHours" = "Время работы системы"
@ -246,6 +246,8 @@
"pageSize" = "Размер нумерации страниц" "pageSize" = "Размер нумерации страниц"
"pageSizeDesc" = "Определить размер страницы для входящей таблицы. Установите 0, чтобы отключить" "pageSizeDesc" = "Определить размер страницы для входящей таблицы. Установите 0, чтобы отключить"
"remarkModel" = "Модель примечания и символ разделения" "remarkModel" = "Модель примечания и символ разделения"
"datepicker" = "выбор даты"
"datepickerDescription" = "Тип календаря выбора указывает дату истечения срока действия."
"sampleRemark" = "Пример замечания" "sampleRemark" = "Пример замечания"
"oldUsername" = "Текущее имя пользователя" "oldUsername" = "Текущее имя пользователя"
"currentPassword" = "Текущий пароль" "currentPassword" = "Текущий пароль"
@ -327,10 +329,8 @@
"PrivateIpDesc" = "Изменение шаблона конфигурации для предупреждения подключения к диапазонам частных IP-адресов" "PrivateIpDesc" = "Изменение шаблона конфигурации для предупреждения подключения к диапазонам частных IP-адресов"
"Ads" = "Блокировка рекламы" "Ads" = "Блокировка рекламы"
"AdsDesc" = "Изменение конфигурации для блокировки рекламы" "AdsDesc" = "Изменение конфигурации для блокировки рекламы"
"Family" = "Блокируйте вредоносное ПО и контент для взрослых" "Family" = "Блокировать вредоносное ПО и контент для взрослых"
"FamilyDesc" = "DNS-преобразователи Cloudflare для блокировки вредоносного ПО и контента для взрослых в целях защиты семьи." "FamilyDesc" = "Резольверы DNS для блокировки вредоносных программ и контента для взрослых для защиты семьи"
"Security" = "Блокируйте вредоносное ПО, фишинговые сайты и сайты криптомайнеров"
"SecurityDesc" = "Изменение шаблона конфигурации для защиты безопасности."
"Speedtest" = "Блокировать сайты для проверки скорости" "Speedtest" = "Блокировать сайты для проверки скорости"
"SpeedtestDesc" = "Изменение шаблона конфигурации для предупреждения подключения к веб-сайтам для тестирования скорости" "SpeedtestDesc" = "Изменение шаблона конфигурации для предупреждения подключения к веб-сайтам для тестирования скорости"
"IRIp" = "Заблокировать подключения к диапазонам IP-адресов Ирана" "IRIp" = "Заблокировать подключения к диапазонам IP-адресов Ирана"

View file

@ -74,12 +74,12 @@
[pages.index] [pages.index]
"title" = "Trạng thái hệ thống" "title" = "Trạng thái hệ thống"
"memory" = "ĐẬP" "memory" = "Bộ nhớ"
"hard" = "Đĩa" "hard" = "Ổ cứng"
"xrayStatus" = "Trạng thái" "xrayStatus" = "Trạng thái của Xray"
"stopXray" = "Dừng lại" "stopXray" = "Dừng Xray"
"restartXray" = "Khởi động lại" "restartXray" = "Khởi động lại Xray"
"xraySwitch" = "Phiên bản" "xraySwitch" = "Chuyển đổi phiên bản"
"xraySwitchClick" = "Chọn phiên bản mà bạn muốn chuyển đổi sang." "xraySwitchClick" = "Chọn phiên bản mà bạn muốn chuyển đổi sang."
"xraySwitchClickDesk" = "Hãy lựa chọn thận trọng, vì các phiên bản cũ có thể không tương thích với các cấu hình hiện tại." "xraySwitchClickDesk" = "Hãy lựa chọn thận trọng, vì các phiên bản cũ có thể không tương thích với các cấu hình hiện tại."
"operationHours" = "Thời gian hoạt động" "operationHours" = "Thời gian hoạt động"
@ -246,6 +246,8 @@
"pageSize" = "Kích thước phân trang" "pageSize" = "Kích thước phân trang"
"pageSizeDesc" = "Xác định kích thước trang cho bảng gửi đến. Đặt 0 để tắt" "pageSizeDesc" = "Xác định kích thước trang cho bảng gửi đến. Đặt 0 để tắt"
"remarkModel" = "Ghi chú mô hình và ký tự phân tách" "remarkModel" = "Ghi chú mô hình và ký tự phân tách"
"datepicker" = "bảng chọn ngày"
"datepickerDescription" = "Loại lịch chọn chỉ định ngày hết hạn"
"sampleRemark" = "Nhận xét mẫu" "sampleRemark" = "Nhận xét mẫu"
"oldUsername" = "Tên người dùng hiện tại" "oldUsername" = "Tên người dùng hiện tại"
"currentPassword" = "Mật khẩu hiện tại" "currentPassword" = "Mật khẩu hiện tại"
@ -327,10 +329,8 @@
"PrivateIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP riêng tư." "PrivateIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP riêng tư."
"Ads" = "Chặn Quảng cáo" "Ads" = "Chặn Quảng cáo"
"AdsDesc" = "Thay đổi mẫu cấu hình để chặn quảng cáo." "AdsDesc" = "Thay đổi mẫu cấu hình để chặn quảng cáo."
"Family" = "Chặn phần mềm độc hại và nội dung người lớn" "Family" = "Chặn Phần mềm độc hại và Nội dung cho Người lớn"
"FamilyDesc" = "Trình phân giải DNS của Cloudflare để chặn phần mềm độc hại và nội dung người lớn để bảo vệ gia đình." "FamilyDesc" = "Các trình giải quyết DNS để chặn phần mềm độc hại và nội dung cho bảo vệ gia đình."
"Security" = "Chặn các trang web chứa phần mềm độc hại, lừa đảo và khai thác tiền điện tử"
"SecurityDesc" = "Thay đổi mẫu cấu hình để bảo vệ Bảo mật."
"Speedtest" = "Chặn Trang web Speedtest" "Speedtest" = "Chặn Trang web Speedtest"
"SpeedtestDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các trang web Speedtest." "SpeedtestDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các trang web Speedtest."
"IRIp" = "Vô hiệu hóa kết nối đến dải IP của Iran" "IRIp" = "Vô hiệu hóa kết nối đến dải IP của Iran"

View file

@ -10,8 +10,8 @@
"remark" = "备注" "remark" = "备注"
"enable" = "启用" "enable" = "启用"
"protocol" = "协议" "protocol" = "协议"
"search" = "搜" "search" = "搜"
"filter" = "筛选" "filter" = "过滤器"
"loading" = "加载中..." "loading" = "加载中..."
"second" = "秒" "second" = "秒"
"minute" = "分钟" "minute" = "分钟"
@ -30,8 +30,8 @@
"sure" = "确定" "sure" = "确定"
"encryption" = "加密" "encryption" = "加密"
"transmission" = "传输" "transmission" = "传输"
"host" = "Host" "host" = "主持人"
"path" = "Path" "path" = "小路"
"camouflage" = "伪装" "camouflage" = "伪装"
"status" = "状态" "status" = "状态"
"enabled" = "开启" "enabled" = "开启"
@ -49,8 +49,8 @@
"install" = "安装" "install" = "安装"
"clients" = "客户端" "clients" = "客户端"
"usage" = "用法" "usage" = "用法"
"secretToken" = "安全密钥" "secretToken" = "秘密令牌"
"remained" = "剩余" "remained" = "仍然存在"
"security" = "安全" "security" = "安全"
[menu] [menu]
@ -79,7 +79,7 @@
"xrayStatus" = "状态" "xrayStatus" = "状态"
"stopXray" = "停止" "stopXray" = "停止"
"restartXray" = "重启" "restartXray" = "重启"
"xraySwitch" = "版本" "xraySwitch" = "切换版本"
"xraySwitchClick" = "点击你想切换的版本" "xraySwitchClick" = "点击你想切换的版本"
"xraySwitchClickDesk" = "请谨慎选择,旧版本可能配置不兼容" "xraySwitchClickDesk" = "请谨慎选择,旧版本可能配置不兼容"
"operationHours" = "系统正常运行时间" "operationHours" = "系统正常运行时间"
@ -148,7 +148,7 @@
"client" = "客户" "client" = "客户"
"export" = "导出链接" "export" = "导出链接"
"clone" = "克隆" "clone" = "克隆"
"cloneInbound" = "克隆" "cloneInbound" = "创造"
"cloneInboundContent" = "此入站的所有项目除 Port、Listening IP、Clients 将应用于克隆" "cloneInboundContent" = "此入站的所有项目除 Port、Listening IP、Clients 将应用于克隆"
"cloneInboundOk" = "从创建克隆" "cloneInboundOk" = "从创建克隆"
"resetAllTraffic" = "重置所有入站流量" "resetAllTraffic" = "重置所有入站流量"
@ -246,6 +246,8 @@
"pageSize" = "分页大小" "pageSize" = "分页大小"
"pageSizeDesc" = "定义入站表的页面大小。设置 0 表示禁用" "pageSizeDesc" = "定义入站表的页面大小。设置 0 表示禁用"
"remarkModel" = "备注模型和分隔符" "remarkModel" = "备注模型和分隔符"
"datepicker" = "日期选择器"
"datepickerDescription" = "选择器日历类型指定到期日期"
"sampleRemark" = "备注示例" "sampleRemark" = "备注示例"
"oldUsername" = "原用户名" "oldUsername" = "原用户名"
"currentPassword" = "原密码" "currentPassword" = "原密码"
@ -327,10 +329,8 @@
"PrivateIpDesc" = "更改配置模板以避免连接私有 IP 范围" "PrivateIpDesc" = "更改配置模板以避免连接私有 IP 范围"
"Ads" = "屏蔽广告" "Ads" = "屏蔽广告"
"AdsDesc" = "修改配置模板屏蔽广告" "AdsDesc" = "修改配置模板屏蔽广告"
"Family" = "阻止恶意软件和成人内容" "Family" = "启用家庭友好配置"
"FamilyDesc" = "Cloudflare DNS 解析器可阻止恶意软件和成人内容以保护家庭." "FamilyDesc" = "避免为家人连接到不安全的网站"
"Security" = "阻止恶意软件、网络钓鱼和加密货币挖矿网站"
"SecurityDesc" = "更改安全防护配置模板."
"Speedtest" = "阻止测速网站" "Speedtest" = "阻止测速网站"
"SpeedtestDesc" = "更改配置模板以避免连接到速度测试网站。 重新启动面板以应用更改。" "SpeedtestDesc" = "更改配置模板以避免连接到速度测试网站。 重新启动面板以应用更改。"
"IRIp" = "禁止伊朗 IP 范围连接" "IRIp" = "禁止伊朗 IP 范围连接"
@ -379,7 +379,7 @@
"SpotifyWARPDesc" = "为Spotify添加路由到WARP" "SpotifyWARPDesc" = "为Spotify添加路由到WARP"
"IRWARP" = "将伊朗域名路由到 WARP" "IRWARP" = "将伊朗域名路由到 WARP"
"IRWARPDesc" = "将伊朗域的路由添加到 WARP。 重启面板生效" "IRWARPDesc" = "将伊朗域的路由添加到 WARP。 重启面板生效"
"Inbounds" = "入站" "Inbounds" = "界内"
"InboundsDesc" = "更改配置模板接受特殊客户端" "InboundsDesc" = "更改配置模板接受特殊客户端"
"Outbounds" = "出站" "Outbounds" = "出站"
"OutboundsDesc" = "更改配置模板定义此服务器的传出方式" "OutboundsDesc" = "更改配置模板定义此服务器的传出方式"
@ -407,7 +407,7 @@
"editOutbound" = "编辑出站" "editOutbound" = "编辑出站"
"editReverse" = "编辑反向" "editReverse" = "编辑反向"
"tag" = "标签" "tag" = "标签"
"tagDesc" = "唯一标记" "tagDesc" = "独特的标签"
"address" = "地址" "address" = "地址"
"reverse" = "反转" "reverse" = "反转"
"domain" = "域名" "domain" = "域名"

118
x-ui.sh
View file

@ -54,10 +54,6 @@ elif [[ "${release}" == "debian" ]]; then
if [[ ${os_version} -lt 10 ]]; then if [[ ${os_version} -lt 10 ]]; then
echo -e "${red} Please use Debian 10 or higher ${plain}\n" && exit 1 echo -e "${red} Please use Debian 10 or higher ${plain}\n" && exit 1
fi fi
elif [[ "${release}" == "almalinux" ]]; then
if [[ ${os_version} -lt 9 ]]; then
echo -e "${red} Please use Almalinux 9 or higher ${plain}\n" && exit 1
fi
elif [[ "${release}" == "arch" ]]; then elif [[ "${release}" == "arch" ]]; then
echo "Your OS is ArchLinux" echo "Your OS is ArchLinux"
elif [[ "${release}" == "manjaro" ]]; then elif [[ "${release}" == "manjaro" ]]; then
@ -104,7 +100,7 @@ before_show_menu() {
} }
install() { install() {
bash <(curl -Ls https://raw.githubusercontent.com/MHSanaei/3x-ui/main/install.sh) bash <(curl -Ls https://raw.githubusercontent.com/alirahimi818/3x-ui/main/install.sh)
if [[ $? == 0 ]]; then if [[ $? == 0 ]]; then
if [[ $# == 0 ]]; then if [[ $# == 0 ]]; then
start start
@ -123,31 +119,13 @@ update() {
fi fi
return 0 return 0
fi fi
bash <(curl -Ls https://raw.githubusercontent.com/MHSanaei/3x-ui/main/install.sh) bash <(curl -Ls https://raw.githubusercontent.com/alirahimi818/3x-ui/main/install.sh)
if [[ $? == 0 ]]; then if [[ $? == 0 ]]; then
LOGI "Update is complete, Panel has automatically restarted " LOGI "Update is complete, Panel has automatically restarted "
exit 0 exit 0
fi fi
} }
custom_version() {
echo "Enter the panel version (like 2.0.0):"
read panel_version
if [ -z "$panel_version" ]; then
echo "Panel version cannot be empty. Exiting."
exit 1
fi
download_link="https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh"
# Use the entered panel version in the download link
install_command="bash <(curl -Ls $download_link) v$panel_version"
echo "Downloading and installing panel version $panel_version..."
eval $install_command
}
uninstall() { uninstall() {
confirm "Are you sure you want to uninstall the panel? xray will also uninstalled!" "n" confirm "Are you sure you want to uninstall the panel? xray will also uninstalled!" "n"
if [[ $? != 0 ]]; then if [[ $? != 0 ]]; then
@ -375,7 +353,7 @@ enable_bbr() {
} }
update_shell() { update_shell() {
wget -O /usr/bin/x-ui -N --no-check-certificate https://github.com/MHSanaei/3x-ui/raw/main/x-ui.sh wget -O /usr/bin/x-ui -N --no-check-certificate https://github.com/alirahimi818/3x-ui/raw/main/x-ui.sh
if [[ $? != 0 ]]; then if [[ $? != 0 ]]; then
echo "" echo ""
LOGE "Failed to download script, Please check whether the machine can connect Github" LOGE "Failed to download script, Please check whether the machine can connect Github"
@ -1057,37 +1035,36 @@ show_menu() {
${green}3X-ui Panel Management Script${plain} ${green}3X-ui Panel Management Script${plain}
${green}0.${plain} Exit Script ${green}0.${plain} Exit Script
———————————————— ————————————————
${green}1.${plain} Install ${green}1.${plain} Install x-ui
${green}2.${plain} Update ${green}2.${plain} Update x-ui
${green}3.${plain} Custom Version ${green}3.${plain} Uninstall x-ui
${green}4.${plain} Uninstall
———————————————— ————————————————
${green}5.${plain} Reset Username & Password & Secret Token ${green}4.${plain} Reset Username & Password & Secret Token
${green}6.${plain} Reset Settings ${green}5.${plain} Reset Panel Settings
${green}7.${plain} Change Port ${green}6.${plain} Change Panel Port
${green}8.${plain} View Current Settings ${green}7.${plain} View Current Panel Settings
———————————————— ————————————————
${green}9.${plain} Start ${green}8.${plain} Start x-ui
${green}10.${plain} Stop ${green}9.${plain} Stop x-ui
${green}11.${plain} Restart ${green}10.${plain} Restart x-ui
${green}12.${plain} Check Status ${green}11.${plain} Check x-ui Status
${green}13.${plain} Check Logs ${green}12.${plain} Check x-ui Logs
———————————————— ————————————————
${green}14.${plain} Enable x-ui On System Startup ${green}13.${plain} Enable x-ui On System Startup
${green}15.${plain} Disable x-ui On System Startup ${green}14.${plain} Disable x-ui On System Startup
———————————————— ————————————————
${green}16.${plain} SSL Certificate Management ${green}15.${plain} SSL Certificate Management
${green}17.${plain} Cloudflare SSL Certificate ${green}16.${plain} Cloudflare SSL Certificate
${green}18.${plain} IP Limit Management ${green}17.${plain} IP Limit Management
${green}19.${plain} WARP Management ${green}18.${plain} WARP Management
———————————————— ————————————————
${green}20.${plain} Enable BBR ${green}19.${plain} Enable BBR
${green}21.${plain} Update Geo Files ${green}20.${plain} Update Geo Files
${green}22.${plain} Active Firewall and open ports ${green}21.${plain} Active Firewall and open ports
${green}23.${plain} Speedtest by Ookla ${green}22.${plain} Speedtest by Ookla
" "
show_status show_status
echo && read -p "Please enter your selection [0-23]: " num echo && read -p "Please enter your selection [0-22]: " num
case "${num}" in case "${num}" in
0) 0)
@ -1100,70 +1077,67 @@ show_menu() {
check_install && update check_install && update
;; ;;
3) 3)
check_install && custom_version
;;
4)
check_install && uninstall check_install && uninstall
;; ;;
5) 4)
check_install && reset_user check_install && reset_user
;; ;;
6) 5)
check_install && reset_config check_install && reset_config
;; ;;
7) 6)
check_install && set_port check_install && set_port
;; ;;
8) 7)
check_install && check_config check_install && check_config
;; ;;
9) 8)
check_install && start check_install && start
;; ;;
10) 9)
check_install && stop check_install && stop
;; ;;
11) 10)
check_install && restart check_install && restart
;; ;;
12) 11)
check_install && status check_install && status
;; ;;
13) 12)
check_install && show_log check_install && show_log
;; ;;
14) 13)
check_install && enable check_install && enable
;; ;;
15) 14)
check_install && disable check_install && disable
;; ;;
16) 15)
ssl_cert_issue_main ssl_cert_issue_main
;; ;;
17) 16)
ssl_cert_issue_CF ssl_cert_issue_CF
;; ;;
18) 17)
iplimit_main iplimit_main
;; ;;
19) 18)
warp_cloudflare warp_cloudflare
;; ;;
20) 19)
enable_bbr enable_bbr
;; ;;
21) 20)
update_geo update_geo
;; ;;
22) 21)
open_ports open_ports
;; ;;
23) 22)
run_speedtest run_speedtest
;; ;;
*) *)
LOGE "Please enter the correct number [0-23]" LOGE "Please enter the correct number [0-22]"
;; ;;
esac esac
} }