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
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 {

View file

@ -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

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"`
SubShowInfo bool `json:"subShowInfo" form:"subShowInfo"`
SubURI string `json:"subURI" form:"subURI"`
Datepicker string `json:"datepicker" form:"datepicker"`
}
func (s *AllSetting) CheckValid() error {

View file

@ -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;
},

View file

@ -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

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-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">

View file

@ -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>

View file

@ -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">

View file

@ -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;
},

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/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) {

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.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);

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.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);

View file

@ -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'>

View file

@ -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{})

View file

@ -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"

View file

@ -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"

View file

@ -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" = "جلوگیری از اتصال آیپی های ایران"

View file

@ -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-адресов Ирана"

View file

@ -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"

View file

@ -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
View file

@ -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
}