mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-09-05 01:36:19 +00:00
added datepicker option in setting page
jalalian datepicker component was added translate files for datepicker updated
This commit is contained in:
parent
bbcab768ca
commit
fe36d066ee
25 changed files with 1482 additions and 149 deletions
|
@ -20,6 +20,7 @@ type SubService struct {
|
|||
address string
|
||||
showInfo bool
|
||||
remarkModel string
|
||||
datepicker string
|
||||
inboundService service.InboundService
|
||||
settingService service.SettingService
|
||||
}
|
||||
|
@ -39,6 +40,10 @@ func (s *SubService) GetSubs(subId string, host string, showInfo bool) ([]string
|
|||
if err != nil {
|
||||
s.remarkModel = "-ieo"
|
||||
}
|
||||
s.datepicker, err = s.settingService.GetDatepicker()
|
||||
if err != nil {
|
||||
s.datepicker = "gregorian"
|
||||
}
|
||||
for _, inbound := range inbounds {
|
||||
clients, err := s.inboundService.GetClients(inbound)
|
||||
if err != nil {
|
||||
|
|
|
@ -12,6 +12,7 @@ class AllSetting {
|
|||
this.expireDiff = "";
|
||||
this.trafficDiff = "";
|
||||
this.remarkModel = "-ieo";
|
||||
this.datepicker = "gregorian";
|
||||
this.tgBotEnable = false;
|
||||
this.tgBotToken = "";
|
||||
this.tgBotChatId = "";
|
||||
|
|
1252
web/assets/moment/moment-jalali.min.js
vendored
Normal file
1252
web/assets/moment/moment-jalali.min.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
web/assets/persian-datepicker/persian-datepicker.min.css
vendored
Normal file
1
web/assets/persian-datepicker/persian-datepicker.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
web/assets/persian-datepicker/persian-datepicker.min.js
vendored
Normal file
1
web/assets/persian-datepicker/persian-datepicker.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -47,6 +47,7 @@ type AllSetting struct {
|
|||
SubEncrypt bool `json:"subEncrypt" form:"subEncrypt"`
|
||||
SubShowInfo bool `json:"subShowInfo" form:"subShowInfo"`
|
||||
SubURI string `json:"subURI" form:"subURI"`
|
||||
Datepicker string `json:"datepicker" form:"datepicker"`
|
||||
}
|
||||
|
||||
func (s *AllSetting) CheckValid() error {
|
||||
|
|
|
@ -104,8 +104,10 @@
|
|||
<a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</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>
|
||||
<persian-datepicker v-else :dropdown-class-name="themeSwitcher.currentTheme"
|
||||
value="clientsBulkModal.expiryTime" v-model="clientsBulkModal.expiryTime"></persian-datepicker>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="clientsBulkModal.expiryTime != 0">
|
||||
<template slot="label">
|
||||
|
@ -234,6 +236,9 @@
|
|||
get delayedExpireDays() {
|
||||
return this.clientsBulkModal.expiryTime < 0 ? this.clientsBulkModal.expiryTime / -86400000 : 0;
|
||||
},
|
||||
get datepicker() {
|
||||
return app.datepicker;
|
||||
},
|
||||
set delayedExpireDays(days) {
|
||||
this.clientsBulkModal.expiryTime = -86400000 * days;
|
||||
},
|
||||
|
|
|
@ -94,6 +94,9 @@
|
|||
get isEdit() {
|
||||
return this.clientModal.isEdit;
|
||||
},
|
||||
get datepicker() {
|
||||
return app.datepicker;
|
||||
},
|
||||
get isTrafficExhausted() {
|
||||
if (!clientStats) return false
|
||||
if (clientStats.total <= 0) return false
|
||||
|
|
59
web/html/xui/component/persianDatepicker.html
Normal file
59
web/html/xui/component/persianDatepicker.html
Normal 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}}
|
|
@ -150,8 +150,10 @@
|
|||
<a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</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>
|
||||
<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-form-item>
|
||||
<a-form-item v-if="client.expiryTime != 0">
|
||||
|
|
|
@ -54,9 +54,11 @@
|
|||
<a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</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="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>
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
</template>
|
||||
</a-form-item>
|
||||
<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 :wrapper-col="{span:24}">
|
||||
<a-input-group compact v-for="(header, index) in inbound.stream.tcp.request.headers">
|
||||
|
|
|
@ -63,6 +63,9 @@
|
|||
get client() {
|
||||
return inModal.inbound.clients[0];
|
||||
},
|
||||
get datepicker() {
|
||||
return app.datepicker;
|
||||
},
|
||||
get delayedExpireDays() {
|
||||
return this.client && this.client.expiryTime < 0 ? this.client.expiryTime / -86400000 : 0;
|
||||
},
|
||||
|
|
|
@ -446,6 +446,7 @@
|
|||
<script src="{{ .base_path }}assets/js/model/xray.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/js/model/dbinbound.js?{{ .cur_ver }}"></script>
|
||||
{{template "component/themeSwitcher" .}}
|
||||
{{template "component/persianDatepicker" .}}
|
||||
<script>
|
||||
const columns = [{
|
||||
title: "ID",
|
||||
|
@ -539,6 +540,7 @@
|
|||
data: {
|
||||
siderDrawer,
|
||||
themeSwitcher,
|
||||
persianDatepicker,
|
||||
spinning: false,
|
||||
inbounds: [],
|
||||
dbInbounds: [],
|
||||
|
@ -560,6 +562,7 @@
|
|||
subURI : ''
|
||||
},
|
||||
remarkModel: '-ieo',
|
||||
datepicker: 'gregorian',
|
||||
tgBotEnable: false,
|
||||
pageSize: 0,
|
||||
isMobile: window.innerWidth <= 768,
|
||||
|
@ -605,6 +608,7 @@
|
|||
};
|
||||
this.pageSize = pageSize;
|
||||
this.remarkModel = remarkModel;
|
||||
this.datepicker = datepicker;
|
||||
}
|
||||
},
|
||||
setInbounds(dbInbounds) {
|
||||
|
|
|
@ -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.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>
|
||||
<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-row style="padding: 20px">
|
||||
<a-col :lg="24" :xl="12">
|
||||
|
@ -197,7 +218,7 @@
|
|||
<td>
|
||||
<a-form-item>
|
||||
<password-input v-model="user.newPassword" style="width: 200px"></password-input>
|
||||
</a-form-item>
|
||||
</a-form-item>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -311,6 +332,7 @@
|
|||
showAlert: false,
|
||||
remarkModels: {i:'Inbound',e:'Email',o:'Other'},
|
||||
remarkSeparators: [' ','-','_','@',':','~','|',',','.','/'],
|
||||
datepickerList: [{name:'Gregorian (Standard)', value: 'gregorian'}, {name:'Jalalian (شمسی)', value: 'jalalian'}],
|
||||
remarkSample: '',
|
||||
get remarkModel() {
|
||||
rm = this.allSetting.remarkModel;
|
||||
|
@ -328,11 +350,17 @@
|
|||
this.allSetting.remarkModel = value + this.allSetting.remarkModel.substring(1);
|
||||
this.changeRemarkSample();
|
||||
},
|
||||
get datepicker() {
|
||||
return this.allSetting.datepicker ? this.allSetting.datepicker : 'gregorian';
|
||||
},
|
||||
set datepicker(value) {
|
||||
this.allSetting.datepicker = value;
|
||||
},
|
||||
changeRemarkSample(){
|
||||
sample = []
|
||||
this.remarkModel.forEach(r => sample.push(this.remarkModels[r]));
|
||||
this.remarkSample = sample.length == 0 ? '' : sample.join(this.remarkSeparator);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loading(spinning = true) {
|
||||
|
@ -384,7 +412,9 @@
|
|||
if (msg.success) {
|
||||
this.loading(true);
|
||||
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 url = buildURL({ host, port, isTLS, base, path: "panel/settings" });
|
||||
window.location.replace(url);
|
||||
|
|
|
@ -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.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.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>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel header='{{ i18n "pages.xray.blockCountryConfigs"}}'>
|
||||
|
@ -545,11 +544,6 @@
|
|||
"geosite: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"],
|
||||
openai: ["geosite:openai"],
|
||||
google: ["geosite:google"],
|
||||
|
@ -566,7 +560,7 @@
|
|||
ir: [
|
||||
"regexp:.*\\.ir$",
|
||||
"regexp:.*\\.xn--mgba3a4f16a$", // .ایران
|
||||
"ext:geosite_IR.dat:ir"
|
||||
"ext:geosite_IR.dat:ir" // have rules to bypass all .ir domains.
|
||||
],
|
||||
vn: [
|
||||
"regexp:.*\\.vn$",
|
||||
|
@ -577,7 +571,9 @@
|
|||
familyProtectDNS: {
|
||||
"servers": [
|
||||
"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"
|
||||
},
|
||||
|
@ -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: {
|
||||
get: function () {
|
||||
return doAllItemsExist(this.settingsData.domains.speedtest, this.blockedDomains);
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label='Protocol'>
|
||||
<a-select v-model="ruleModal.rule.protocol" mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option v-for="x in ['http','tls','bittorrent']" :value="x">[[ x ]]</a-select-option>
|
||||
<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>
|
||||
</a-form-item>
|
||||
<a-form-item label='Attributes'>
|
||||
|
|
|
@ -56,6 +56,7 @@ var defaultValueMap = map[string]string{
|
|||
"subEncrypt": "true",
|
||||
"subShowInfo": "true",
|
||||
"subURI": "",
|
||||
"datepicker": "gregorian",
|
||||
}
|
||||
|
||||
type SettingService struct {
|
||||
|
@ -417,6 +418,10 @@ func (s *SettingService) GetSubURI() (string, error) {
|
|||
return s.getString("subURI")
|
||||
}
|
||||
|
||||
func (s *SettingService) GetDatepicker() (string, error) {
|
||||
return s.getString("datepicker")
|
||||
}
|
||||
|
||||
func (s *SettingService) GetPageSize() (int, error) {
|
||||
return s.getInt("pageSize")
|
||||
}
|
||||
|
@ -463,6 +468,7 @@ func (s *SettingService) GetDefaultSettings(host string) (interface{}, error) {
|
|||
"subEnable": func() (interface{}, error) { return s.GetSubEnable() },
|
||||
"subURI": func() (interface{}, error) { return s.GetSubURI() },
|
||||
"remarkModel": func() (interface{}, error) { return s.GetRemarkModel() },
|
||||
"datepicker": func() (interface{}, error) { return s.GetDatepicker() },
|
||||
}
|
||||
|
||||
result := make(map[string]interface{})
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
"settings" = "Panel Settings"
|
||||
"xray" = "Xray Settings"
|
||||
"logout" = "Logout"
|
||||
"link" = "Manage"
|
||||
"link" = "Management"
|
||||
|
||||
[pages.login]
|
||||
"title" = "Login"
|
||||
|
@ -79,7 +79,7 @@
|
|||
"xrayStatus" = "Status"
|
||||
"stopXray" = "Stop"
|
||||
"restartXray" = "Restart"
|
||||
"xraySwitch" = "Version"
|
||||
"xraySwitch" = "SwitchV"
|
||||
"xraySwitchClick" = "Choose the version you want to switch to."
|
||||
"xraySwitchClickDesk" = "Choose wisely, as older versions may not be compatible with current configurations."
|
||||
"operationHours" = "Uptime"
|
||||
|
@ -246,6 +246,8 @@
|
|||
"pageSize" = "Pagination Size"
|
||||
"pageSizeDesc" = "Define page size for inbounds table. Set 0 to disable"
|
||||
"remarkModel" = "Remark Model and Seperation Charachter"
|
||||
"datepicker" = "Datepicker"
|
||||
"datepickerDescription" = "Selector calendar type specifies the expiration date"
|
||||
"sampleRemark" = "Sample Remark"
|
||||
"oldUsername" = "Current Username"
|
||||
"currentPassword" = "Current Password"
|
||||
|
@ -327,10 +329,8 @@
|
|||
"PrivateIpDesc" = "Change the configuration template to avoid connecting to private IP ranges."
|
||||
"Ads" = "Block Ads"
|
||||
"AdsDesc" = "Change the configuration template to block ads."
|
||||
"Family" = "Block malware and Adult Content"
|
||||
"FamilyDesc" = "Cloudflare 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."
|
||||
"Family" = "Block Malware and Adult Content"
|
||||
"FamilyDesc" = "DNS resolvers to block malware and adult content for family protection."
|
||||
"Speedtest" = "Block Speedtest Websites"
|
||||
"SpeedtestDesc" = "Change the configuration template to avoid connecting to speedtest websites."
|
||||
"IRIp" = "Disable Connection to Iran IPs"
|
||||
|
|
|
@ -76,10 +76,10 @@
|
|||
"title" = "Estado del Sistema"
|
||||
"memory" = "Memoria"
|
||||
"hard" = "Disco Duro"
|
||||
"xrayStatus" = "Estado de"
|
||||
"stopXray" = "Detener"
|
||||
"xrayStatus" = "Estado de Xray"
|
||||
"stopXray" = "Detener Xray"
|
||||
"restartXray" = "Reiniciar"
|
||||
"xraySwitch" = "Versión"
|
||||
"xraySwitch" = "Cambiar Versión"
|
||||
"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."
|
||||
"operationHours" = "Tiempo de Funcionamiento"
|
||||
|
@ -246,6 +246,8 @@
|
|||
"pageSize" = "Tamaño de paginación"
|
||||
"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"
|
||||
"datepicker" = "selector de fechas"
|
||||
"datepickerDescription" = "El tipo de calendario selector especifica la fecha de vencimiento"
|
||||
"sampleRemark" = "Observación de muestra"
|
||||
"oldUsername" = "Nombre de Usuario 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."
|
||||
"Ads" = "Bloquear Anuncios"
|
||||
"AdsDesc" = "Cambia la plantilla de configuración para bloquear anuncios."
|
||||
"Family" = "Bloquee malware y contenido para adultos"
|
||||
"FamilyDesc" = "Resolutores de DNS de Cloudflare 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."
|
||||
"Family" = "Bloquear Malware y Contenido para Adultos"
|
||||
"FamilyDesc" = "Resolvedores de DNS para bloquear malware y contenido para adultos para protección familiar."
|
||||
"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."
|
||||
"IRIp" = "Desactivar Conexión a Rangos de IP de Irán"
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
"xrayStatus" = "وضعیت"
|
||||
"stopXray" = "توقف"
|
||||
"restartXray" = "شروع مجدد"
|
||||
"xraySwitch" = "ورژن"
|
||||
"xraySwitch" = "تغییر ورژن"
|
||||
"xraySwitchClick" = "ورژن مورد نظر را انتخاب کنید"
|
||||
"xraySwitchClickDesk" = "لطفا با دقت انتخاب کنید ، در صورت انتخاب اشتباه امکان قطعی سیستم وجود دارد "
|
||||
"operationHours" = "آپ تایم سیستم"
|
||||
|
@ -246,6 +246,8 @@
|
|||
"pageSize" = "اندازه صفحه بندی جدول"
|
||||
"pageSizeDesc" = "اندازه صفحه را برای جدول سرویس ها تعریف کنید. 0: غیرفعال"
|
||||
"remarkModel" = "نام کانفیگ و جداکننده"
|
||||
"datepicker" = "انتخاب کننده تاریخ"
|
||||
"datepickerDescription" = "نوع تقویم انتخاب کننده تاریخ انقضا را مشخص میکند "
|
||||
"sampleRemark" = "نمونه نام"
|
||||
"oldUsername" = "نام کاربری فعلی"
|
||||
"currentPassword" = "رمز عبور فعلی"
|
||||
|
@ -328,9 +330,7 @@
|
|||
"Ads" = "مسدود کردن تبلیغات"
|
||||
"AdsDesc" = "الگوی تنظیمات را برای مسدود کردن تبلیغات تغییر میدهد"
|
||||
"Family" = "فعال کردن حالت خانواده"
|
||||
"FamilyDesc" = "مسدود کردن محتوای بزرگسالان به کمک دی ان اس کلودفلر برای حالت خانواده "
|
||||
"Security" = "مسدود کردن وبسایتهای بدافزار، فیشینگ و کریپتومینرها"
|
||||
"SecurityDesc" = "الگوی پیکربندی را برای حفاظت از امنیت تغییر دهید"
|
||||
"FamilyDesc" = "برای جلوگیری از ارتباط با وبسایت های ناامن"
|
||||
"Speedtest" = "جلوگیری از اتصال به سایت های تست سرعت"
|
||||
"SpeedtestDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال به سایت های تست سرعت تغییر میدهد"
|
||||
"IRIp" = "جلوگیری از اتصال آیپی های ایران"
|
||||
|
|
|
@ -77,9 +77,9 @@
|
|||
"memory" = "Память"
|
||||
"hard" = "Жесткий диск"
|
||||
"xrayStatus" = "Статус"
|
||||
"stopXray" = "Остановить"
|
||||
"restartXray" = "Перезапустить"
|
||||
"xraySwitch" = "Версия"
|
||||
"stopXray" = "Остановить Xray"
|
||||
"restartXray" = "Перезапустить Xray"
|
||||
"xraySwitch" = "Переключить версию"
|
||||
"xraySwitchClick" = "Выберите желаемую версию"
|
||||
"xraySwitchClickDesk" = "Выбирайте внимательно, так как старые версии могут быть несовместимы с текущими конфигурациями"
|
||||
"operationHours" = "Время работы системы"
|
||||
|
@ -246,6 +246,8 @@
|
|||
"pageSize" = "Размер нумерации страниц"
|
||||
"pageSizeDesc" = "Определить размер страницы для входящей таблицы. Установите 0, чтобы отключить"
|
||||
"remarkModel" = "Модель примечания и символ разделения"
|
||||
"datepicker" = "выбор даты"
|
||||
"datepickerDescription" = "Тип календаря выбора указывает дату истечения срока действия."
|
||||
"sampleRemark" = "Пример замечания"
|
||||
"oldUsername" = "Текущее имя пользователя"
|
||||
"currentPassword" = "Текущий пароль"
|
||||
|
@ -327,10 +329,8 @@
|
|||
"PrivateIpDesc" = "Изменение шаблона конфигурации для предупреждения подключения к диапазонам частных IP-адресов"
|
||||
"Ads" = "Блокировка рекламы"
|
||||
"AdsDesc" = "Изменение конфигурации для блокировки рекламы"
|
||||
"Family" = "Блокируйте вредоносное ПО и контент для взрослых"
|
||||
"FamilyDesc" = "DNS-преобразователи Cloudflare для блокировки вредоносного ПО и контента для взрослых в целях защиты семьи."
|
||||
"Security" = "Блокируйте вредоносное ПО, фишинговые сайты и сайты криптомайнеров"
|
||||
"SecurityDesc" = "Изменение шаблона конфигурации для защиты безопасности."
|
||||
"Family" = "Блокировать вредоносное ПО и контент для взрослых"
|
||||
"FamilyDesc" = "Резольверы DNS для блокировки вредоносных программ и контента для взрослых для защиты семьи"
|
||||
"Speedtest" = "Блокировать сайты для проверки скорости"
|
||||
"SpeedtestDesc" = "Изменение шаблона конфигурации для предупреждения подключения к веб-сайтам для тестирования скорости"
|
||||
"IRIp" = "Заблокировать подключения к диапазонам IP-адресов Ирана"
|
||||
|
|
|
@ -74,12 +74,12 @@
|
|||
|
||||
[pages.index]
|
||||
"title" = "Trạng thái hệ thống"
|
||||
"memory" = "ĐẬP"
|
||||
"hard" = "Đĩa"
|
||||
"xrayStatus" = "Trạng thái"
|
||||
"stopXray" = "Dừng lại"
|
||||
"restartXray" = "Khởi động lại"
|
||||
"xraySwitch" = "Phiên bản"
|
||||
"memory" = "Bộ nhớ"
|
||||
"hard" = "Ổ cứng"
|
||||
"xrayStatus" = "Trạng thái của Xray"
|
||||
"stopXray" = "Dừng Xray"
|
||||
"restartXray" = "Khởi động lại Xray"
|
||||
"xraySwitch" = "Chuyển đổi phiên bản"
|
||||
"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."
|
||||
"operationHours" = "Thời gian hoạt động"
|
||||
|
@ -246,6 +246,8 @@
|
|||
"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"
|
||||
"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"
|
||||
"oldUsername" = "Tên người dùng 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ư."
|
||||
"Ads" = "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"
|
||||
"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."
|
||||
"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."
|
||||
"Family" = "Chặn Phần mềm độc hại và Nội dung cho Người lớn"
|
||||
"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."
|
||||
"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."
|
||||
"IRIp" = "Vô hiệu hóa kết nối đến dải IP của Iran"
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
"remark" = "备注"
|
||||
"enable" = "启用"
|
||||
"protocol" = "协议"
|
||||
"search" = "搜索"
|
||||
"filter" = "筛选"
|
||||
"search" = "搜尋"
|
||||
"filter" = "过滤器"
|
||||
"loading" = "加载中..."
|
||||
"second" = "秒"
|
||||
"minute" = "分钟"
|
||||
|
@ -30,8 +30,8 @@
|
|||
"sure" = "确定"
|
||||
"encryption" = "加密"
|
||||
"transmission" = "传输"
|
||||
"host" = "Host"
|
||||
"path" = "Path"
|
||||
"host" = "主持人"
|
||||
"path" = "小路"
|
||||
"camouflage" = "伪装"
|
||||
"status" = "状态"
|
||||
"enabled" = "开启"
|
||||
|
@ -49,8 +49,8 @@
|
|||
"install" = "安装"
|
||||
"clients" = "客户端"
|
||||
"usage" = "用法"
|
||||
"secretToken" = "安全密钥"
|
||||
"remained" = "剩余"
|
||||
"secretToken" = "秘密令牌"
|
||||
"remained" = "仍然存在"
|
||||
"security" = "安全"
|
||||
|
||||
[menu]
|
||||
|
@ -79,7 +79,7 @@
|
|||
"xrayStatus" = "状态"
|
||||
"stopXray" = "停止"
|
||||
"restartXray" = "重启"
|
||||
"xraySwitch" = "版本"
|
||||
"xraySwitch" = "切换版本"
|
||||
"xraySwitchClick" = "点击你想切换的版本"
|
||||
"xraySwitchClickDesk" = "请谨慎选择,旧版本可能配置不兼容"
|
||||
"operationHours" = "系统正常运行时间"
|
||||
|
@ -148,7 +148,7 @@
|
|||
"client" = "客户"
|
||||
"export" = "导出链接"
|
||||
"clone" = "克隆"
|
||||
"cloneInbound" = "克隆"
|
||||
"cloneInbound" = "创造"
|
||||
"cloneInboundContent" = "此入站的所有项目除 Port、Listening IP、Clients 将应用于克隆"
|
||||
"cloneInboundOk" = "从创建克隆"
|
||||
"resetAllTraffic" = "重置所有入站流量"
|
||||
|
@ -246,6 +246,8 @@
|
|||
"pageSize" = "分页大小"
|
||||
"pageSizeDesc" = "定义入站表的页面大小。设置 0 表示禁用"
|
||||
"remarkModel" = "备注模型和分隔符"
|
||||
"datepicker" = "日期选择器"
|
||||
"datepickerDescription" = "选择器日历类型指定到期日期"
|
||||
"sampleRemark" = "备注示例"
|
||||
"oldUsername" = "原用户名"
|
||||
"currentPassword" = "原密码"
|
||||
|
@ -327,10 +329,8 @@
|
|||
"PrivateIpDesc" = "更改配置模板以避免连接私有 IP 范围"
|
||||
"Ads" = "屏蔽广告"
|
||||
"AdsDesc" = "修改配置模板屏蔽广告"
|
||||
"Family" = "阻止恶意软件和成人内容"
|
||||
"FamilyDesc" = "Cloudflare DNS 解析器可阻止恶意软件和成人内容以保护家庭."
|
||||
"Security" = "阻止恶意软件、网络钓鱼和加密货币挖矿网站"
|
||||
"SecurityDesc" = "更改安全防护配置模板."
|
||||
"Family" = "启用家庭友好配置"
|
||||
"FamilyDesc" = "避免为家人连接到不安全的网站"
|
||||
"Speedtest" = "阻止测速网站"
|
||||
"SpeedtestDesc" = "更改配置模板以避免连接到速度测试网站。 重新启动面板以应用更改。"
|
||||
"IRIp" = "禁止伊朗 IP 范围连接"
|
||||
|
@ -379,7 +379,7 @@
|
|||
"SpotifyWARPDesc" = "为Spotify添加路由到WARP"
|
||||
"IRWARP" = "将伊朗域名路由到 WARP"
|
||||
"IRWARPDesc" = "将伊朗域的路由添加到 WARP。 重启面板生效"
|
||||
"Inbounds" = "入站"
|
||||
"Inbounds" = "界内"
|
||||
"InboundsDesc" = "更改配置模板接受特殊客户端"
|
||||
"Outbounds" = "出站"
|
||||
"OutboundsDesc" = "更改配置模板定义此服务器的传出方式"
|
||||
|
@ -407,7 +407,7 @@
|
|||
"editOutbound" = "编辑出站"
|
||||
"editReverse" = "编辑反向"
|
||||
"tag" = "标签"
|
||||
"tagDesc" = "唯一标记"
|
||||
"tagDesc" = "独特的标签"
|
||||
"address" = "地址"
|
||||
"reverse" = "反转"
|
||||
"domain" = "域名"
|
||||
|
|
118
x-ui.sh
118
x-ui.sh
|
@ -54,10 +54,6 @@ elif [[ "${release}" == "debian" ]]; then
|
|||
if [[ ${os_version} -lt 10 ]]; then
|
||||
echo -e "${red} Please use Debian 10 or higher ${plain}\n" && exit 1
|
||||
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
|
||||
echo "Your OS is ArchLinux"
|
||||
elif [[ "${release}" == "manjaro" ]]; then
|
||||
|
@ -104,7 +100,7 @@ before_show_menu() {
|
|||
}
|
||||
|
||||
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
|
||||
start
|
||||
|
@ -123,31 +119,13 @@ update() {
|
|||
fi
|
||||
return 0
|
||||
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
|
||||
LOGI "Update is complete, Panel has automatically restarted "
|
||||
exit 0
|
||||
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() {
|
||||
confirm "Are you sure you want to uninstall the panel? xray will also uninstalled!" "n"
|
||||
if [[ $? != 0 ]]; then
|
||||
|
@ -375,7 +353,7 @@ enable_bbr() {
|
|||
}
|
||||
|
||||
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
|
||||
echo ""
|
||||
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}0.${plain} Exit Script
|
||||
————————————————
|
||||
${green}1.${plain} Install
|
||||
${green}2.${plain} Update
|
||||
${green}3.${plain} Custom Version
|
||||
${green}4.${plain} Uninstall
|
||||
${green}1.${plain} Install x-ui
|
||||
${green}2.${plain} Update x-ui
|
||||
${green}3.${plain} Uninstall x-ui
|
||||
————————————————
|
||||
${green}5.${plain} Reset Username & Password & Secret Token
|
||||
${green}6.${plain} Reset Settings
|
||||
${green}7.${plain} Change Port
|
||||
${green}8.${plain} View Current Settings
|
||||
${green}4.${plain} Reset Username & Password & Secret Token
|
||||
${green}5.${plain} Reset Panel Settings
|
||||
${green}6.${plain} Change Panel Port
|
||||
${green}7.${plain} View Current Panel Settings
|
||||
————————————————
|
||||
${green}9.${plain} Start
|
||||
${green}10.${plain} Stop
|
||||
${green}11.${plain} Restart
|
||||
${green}12.${plain} Check Status
|
||||
${green}13.${plain} Check Logs
|
||||
${green}8.${plain} Start x-ui
|
||||
${green}9.${plain} Stop x-ui
|
||||
${green}10.${plain} Restart x-ui
|
||||
${green}11.${plain} Check x-ui Status
|
||||
${green}12.${plain} Check x-ui Logs
|
||||
————————————————
|
||||
${green}14.${plain} Enable x-ui On System Startup
|
||||
${green}15.${plain} Disable x-ui On System Startup
|
||||
${green}13.${plain} Enable x-ui On System Startup
|
||||
${green}14.${plain} Disable x-ui On System Startup
|
||||
————————————————
|
||||
${green}16.${plain} SSL Certificate Management
|
||||
${green}17.${plain} Cloudflare SSL Certificate
|
||||
${green}18.${plain} IP Limit Management
|
||||
${green}19.${plain} WARP Management
|
||||
${green}15.${plain} SSL Certificate Management
|
||||
${green}16.${plain} Cloudflare SSL Certificate
|
||||
${green}17.${plain} IP Limit Management
|
||||
${green}18.${plain} WARP Management
|
||||
————————————————
|
||||
${green}20.${plain} Enable BBR
|
||||
${green}21.${plain} Update Geo Files
|
||||
${green}22.${plain} Active Firewall and open ports
|
||||
${green}23.${plain} Speedtest by Ookla
|
||||
${green}19.${plain} Enable BBR
|
||||
${green}20.${plain} Update Geo Files
|
||||
${green}21.${plain} Active Firewall and open ports
|
||||
${green}22.${plain} Speedtest by Ookla
|
||||
"
|
||||
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
|
||||
0)
|
||||
|
@ -1100,70 +1077,67 @@ show_menu() {
|
|||
check_install && update
|
||||
;;
|
||||
3)
|
||||
check_install && custom_version
|
||||
;;
|
||||
4)
|
||||
check_install && uninstall
|
||||
;;
|
||||
5)
|
||||
4)
|
||||
check_install && reset_user
|
||||
;;
|
||||
6)
|
||||
5)
|
||||
check_install && reset_config
|
||||
;;
|
||||
7)
|
||||
6)
|
||||
check_install && set_port
|
||||
;;
|
||||
8)
|
||||
7)
|
||||
check_install && check_config
|
||||
;;
|
||||
9)
|
||||
8)
|
||||
check_install && start
|
||||
;;
|
||||
10)
|
||||
9)
|
||||
check_install && stop
|
||||
;;
|
||||
11)
|
||||
10)
|
||||
check_install && restart
|
||||
;;
|
||||
12)
|
||||
11)
|
||||
check_install && status
|
||||
;;
|
||||
13)
|
||||
12)
|
||||
check_install && show_log
|
||||
;;
|
||||
14)
|
||||
13)
|
||||
check_install && enable
|
||||
;;
|
||||
15)
|
||||
14)
|
||||
check_install && disable
|
||||
;;
|
||||
16)
|
||||
15)
|
||||
ssl_cert_issue_main
|
||||
;;
|
||||
17)
|
||||
16)
|
||||
ssl_cert_issue_CF
|
||||
;;
|
||||
18)
|
||||
17)
|
||||
iplimit_main
|
||||
;;
|
||||
19)
|
||||
18)
|
||||
warp_cloudflare
|
||||
;;
|
||||
20)
|
||||
19)
|
||||
enable_bbr
|
||||
;;
|
||||
21)
|
||||
20)
|
||||
update_geo
|
||||
;;
|
||||
22)
|
||||
21)
|
||||
open_ports
|
||||
;;
|
||||
23)
|
||||
22)
|
||||
run_speedtest
|
||||
;;
|
||||
*)
|
||||
LOGE "Please enter the correct number [0-23]"
|
||||
LOGE "Please enter the correct number [0-22]"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue