v3.1.3 init commit

- Fixed #378
- Added wip dark theme
- Fixed in code typo
- Fixed int conversion bug in some DNS challenge supplier
This commit is contained in:
Toby Chui 2024-11-08 22:24:07 +08:00
parent e79a70b7ac
commit 634e9c9855
18 changed files with 629 additions and 122 deletions

View File

@ -230,7 +230,17 @@ func handleCountryBlacklistAdd(w http.ResponseWriter, r *http.Request) {
return
}
rule.AddCountryCodeToBlackList(countryCode, comment)
//Check if the country code contains comma, if yes, split it
if strings.Contains(countryCode, ",") {
codes := strings.Split(countryCode, ",")
for _, code := range codes {
code = strings.TrimSpace(code)
rule.AddCountryCodeToBlackList(code, comment)
}
} else {
countryCode = strings.TrimSpace(countryCode)
rule.AddCountryCodeToBlackList(countryCode, comment)
}
utils.SendOK(w)
}
@ -254,7 +264,17 @@ func handleCountryBlacklistRemove(w http.ResponseWriter, r *http.Request) {
return
}
rule.RemoveCountryCodeFromBlackList(countryCode)
//Check if the country code contains comma, if yes, split it
if strings.Contains(countryCode, ",") {
codes := strings.Split(countryCode, ",")
for _, code := range codes {
code = strings.TrimSpace(code)
rule.RemoveCountryCodeFromBlackList(code)
}
} else {
countryCode = strings.TrimSpace(countryCode)
rule.RemoveCountryCodeFromBlackList(countryCode)
}
utils.SendOK(w)
}
@ -397,7 +417,17 @@ func handleCountryWhitelistAdd(w http.ResponseWriter, r *http.Request) {
p := bluemonday.StrictPolicy()
comment = p.Sanitize(comment)
rule.AddCountryCodeToWhitelist(countryCode, comment)
//Check if the country code contains comma, if yes, split it
if strings.Contains(countryCode, ",") {
codes := strings.Split(countryCode, ",")
for _, code := range codes {
code = strings.TrimSpace(code)
rule.AddCountryCodeToWhitelist(code, comment)
}
} else {
countryCode = strings.TrimSpace(countryCode)
rule.AddCountryCodeToWhitelist(countryCode, comment)
}
utils.SendOK(w)
}
@ -420,7 +450,17 @@ func handleCountryWhitelistRemove(w http.ResponseWriter, r *http.Request) {
return
}
rule.RemoveCountryCodeFromWhitelist(countryCode)
//Check if the country code contains comma, if yes, split it
if strings.Contains(countryCode, ",") {
codes := strings.Split(countryCode, ",")
for _, code := range codes {
code = strings.TrimSpace(code)
rule.RemoveCountryCodeFromWhitelist(code)
}
} else {
countryCode = strings.TrimSpace(countryCode)
rule.RemoveCountryCodeFromWhitelist(countryCode)
}
utils.SendOK(w)
}

View File

@ -60,9 +60,9 @@ var enableAutoUpdate = flag.Bool("cfgupgrade", true, "Enable auto config upgrade
var (
name = "Zoraxy"
version = "3.1.2"
version = "3.1.3"
nodeUUID = "generic" //System uuid, in uuidv4 format
development = false //Set this to false to use embedded web fs
development = true //Set this to false to use embedded web fs
bootTime = time.Now().Unix()
/*

View File

@ -3,7 +3,7 @@ package acme
/*
CA.go
This script load CA defination from embedded ca.json
This script load CA definition from embedded ca.json
*/
import (
_ "embed"
@ -13,7 +13,7 @@ import (
"strings"
)
// CA Defination, load from embeded json when startup
// CA definition, load from embeded json when startup
type CaDef struct {
Production map[string]string
Test map[string]string

View File

@ -1,7 +1,7 @@
package v308
/*
v307 type definations
v307 type definitions
This file wrap up the self-contained data structure
for v3.0.7 structure and allow automatic updates

View File

@ -1,7 +1,7 @@
package v308
/*
v308 type definations
v308 type definition
This file wrap up the self-contained data structure
for v3.0.8 structure and allow automatic updates

View File

@ -1173,7 +1173,7 @@ func HandleCustomHeaderAdd(w http.ResponseWriter, r *http.Request) {
return
}
//Create a Custom Header Defination type
//Create a Custom Header Definition type
var rewriteDirection rewrite.HeaderDirection
if direction == "toOrigin" {
rewriteDirection = rewrite.HeaderDirection_ZoraxyToUpstream

View File

@ -841,6 +841,25 @@
function initBannedCountryList(){
$.get("/api/blacklist/list?type=country&id=" + currentEditingAccessRule, function(data) {
let bannedListHtml = '';
//Check if the country code list contains all eu countries. If yes, replace it with "EU"
let allEu = true;
let euCountries = getEUCCs();
for (var i = 0; i < euCountries.length; i++){
if (!data.includes(euCountries[i])){
allEu = false;
break;
}
}
if (allEu){
//Remove EU countries from the list and replace it with EU
data = data.filter(function(value, index, arr){
return !euCountries.includes(value);
});
data.push("eu");
}
data.forEach((countryCode) => {
bannedListHtml += `
<tr>
@ -919,18 +938,48 @@
//Whitelist country table
function initWhitelistCountryList(){
$.get("/api/whitelist/list?type=country&id=" + currentEditingAccessRule, function(data) {
let bannedListHtml = '';
let whiteListHTML = '';
//Check if the country code list contains all eu countries. If yes, replace it with "EU"
let allEu = true;
let euCountries = getEUCCs();
let countryCodesIndata = data.map(function(item){
//data[n].CC is the country code
return item.CC;
});
for (var i = 0; i < euCountries.length; i++){
if (!countryCodesIndata.includes(euCountries[i])){
allEu = false;
break;
}
}
if (allEu){
//Remove EU countries from the list and replace it with EU
data = data.filter(function(value, index, arr){
return !euCountries.includes(value.CC);
});
data.push({
CC: "eu"
});
}
data.forEach((countryWhitelistEntry) => {
let countryCode = countryWhitelistEntry.CC;
bannedListHtml += `
whiteListHTML += `
<tr>
<td><i class="${countryCode} flag"></i> ${getCountryName(countryCode)} (${countryCode.toUpperCase()})</td>
<td><button class="ui red basic mini icon button" onclick="removeFromWhiteList('${countryCode}')"><i class="trash icon"></i></button></td>
</tr>
`;
});
$('#whitelistCountryList').html(bannedListHtml);
filterCountries(data, "#countrySelectorWhitelist .menu .item");
$('#whitelistCountryList').html(whiteListHTML);
//Map the data.CC to the country code
let countryCodes = data.map(function(item){
return item.CC;
});
filterCountries(countryCodes, "#countrySelectorWhitelist .menu .item");
if (data.length === 0) {
$('#whitelistCountryList').append(`
<tr>
@ -1016,6 +1065,10 @@
});
}
function getEUCCs(){
return ["at","be","bg","cy","cz","de","dk","ee","es","fi","fr","gr","hr","hu","ie","it","lt","lu","lv","mt","nl","pl","pt","se","si","sk"];
}
function addCountryToBlacklist() {
var countryCode = $("#countrySelector").dropdown("get value").toLowerCase();
let ccs = [countryCode];
@ -1025,48 +1078,50 @@
ccs = countryCode.split(",");
}
let counter = 0;
for(var i = 0; i < ccs.length; i++){
let thisCountryCode = ccs[i];
$.cjax({
type: "POST",
url: "/api/blacklist/country/add",
method: "POST",
data: { cc: thisCountryCode, id: currentEditingAccessRule},
success: function(response) {
if (response.error != undefined){
msgbox(response.error, false);
}
if (counter == (ccs.length - 1)){
//Last item
setTimeout(function(){
initBannedCountryList();
if (ccs.length == 1){
//Single country
msgbox(`Added ${getCountryName(ccs[0])} to blacklist`);
}else{
msgbox(ccs.length + " countries added to blacklist");
}
}, (ccs.length==1)?0:100);
}
counter++;
},
error: function(xhr, status, error) {
// handle error response
}
//If the ccs includes "eu", remove the "eu" and add all eu country code to the list
if (ccs.includes("eu")){
ccs = ccs.concat(getEUCCs());
ccs = ccs.filter(function(item){
return item != "eu";
});
}
let counter = ccs.length;
$.cjax({
type: "POST",
url: "/api/blacklist/country/add",
method: "POST",
data: { cc: ccs.join(","), id: currentEditingAccessRule},
success: function(response) {
if (response.error != undefined){
msgbox(response.error, false);
}
initBannedCountryList();
if (ccs.length == 1){
//Single country
msgbox(`Added ${getCountryName(ccs[0])} to blacklist`);
}else{
msgbox(ccs.length + " countries added to blacklist");
}
},
error: function(xhr, status, error) {
// handle error response
}
});
$('#countrySelector').dropdown('clear');
}
function removeFromBannedList(countryCode){
countryCode = countryCode.toLowerCase();
let countryName = getCountryName(countryCode);
if (countryCode == "eu"){
let euCountries = getEUCCs();
countryCode = euCountries.join(",");
countryName = "European Union";
}else{
countryCode = countryCode.toLowerCase();
}
$.cjax({
url: "/api/blacklist/country/remove",
method: "POST",
@ -1162,44 +1217,53 @@
//Usually just a few countries a for loop will get the job done
ccs = countryCode.split(",");
}
let counter = 0;
for(var i = 0; i < ccs.length; i++){
let thisCountryCode = ccs[i];
$.cjax({
type: "POST",
url: "/api/whitelist/country/add",
data: { cc: thisCountryCode , id: currentEditingAccessRule},
success: function(response) {
if (response.error != undefined){
msgbox(response.error, false);
}
if (counter == (ccs.length - 1)){
setTimeout(function(){
initWhitelistCountryList();
if (ccs.length == 1){
//Single country
msgbox(`Added ${getCountryName(ccs[0])} to whitelist`);
}else{
msgbox(ccs.length + " countries added to whitelist");
}
}, (ccs.length==1)?0:100);
}
counter++;
},
error: function(xhr, status, error) {
// handle error response
}
//If the ccs includes "eu", remove the "eu" and add all eu country code to the list
if (ccs.includes("eu")){
ccs = ccs.filter(function(item){
return item != "eu";
});
ccs = ccs.concat(getEUCCs());
}
let counter = ccs.length;
$.cjax({
type: "POST",
url: "/api/whitelist/country/add",
data: { cc: ccs.join(",") , id: currentEditingAccessRule},
success: function(response) {
if (response.error != undefined){
msgbox(response.error, false);
}
initWhitelistCountryList();
if (ccs.length == 1){
//Single country
msgbox(`Added ${getCountryName(ccs[0])} to whitelist`);
}else{
msgbox(ccs.length + " countries added to whitelist");
}
},
error: function(xhr, status, error) {
// handle error response
}
});
$('#countrySelectorWhitelist').dropdown('clear');
}
function removeFromWhiteList(countryCode){
if (confirm("Confirm removing " + getCountryName(countryCode) + " from whitelist?")){
//Remove from whitelist, accepts a country code or "eu" for all EU countries
function removeFromWhiteList(countryCode, skipConfirm = true){
let countryName = getCountryName(countryCode);
if (countryCode == "eu"){
let euCountries = getEUCCs();
countryCode = euCountries.join(",");
countryName = "European Union";
}else{
countryCode = countryCode.toLowerCase();
}
if (skipConfirm || confirm("Confirm removing " + getCountryName(countryCode) + " from whitelist?")){
$.cjax({
url: "/api/whitelist/country/remove",
method: "POST",
@ -1208,6 +1272,7 @@
if (response.error != undefined){
msgbox(response.error, false);
}
msgbox(countryName + " removed from whitelist");
initWhitelistCountryList();
},
error: function(xhr, status, error) {
@ -1276,19 +1341,27 @@
/*
Common Utilities
*/
function filterCountries(codesToShow, selector="#countrySelector .menu .item") {
function filterCountries(alreadySelectedCCs, selector="#countrySelector .menu .item") {
// get all items in the dropdown
const items = document.querySelectorAll(selector);
const euCountries = getEUCCs();
//Replce "eu" in alreadySelectedCCs with all EU countries
if (alreadySelectedCCs.includes("eu")){
alreadySelectedCCs = alreadySelectedCCs.filter(function(item){
return item != "eu";
});
alreadySelectedCCs = alreadySelectedCCs.concat(euCountries);
}
// loop through all items
items.forEach(item => {
// get the value of the item (i.e. the country code)
const code = item.dataset.value;
// if the code is in the array of codes to show, show the item
if (codesToShow.includes(code)) {
if (alreadySelectedCCs.includes(code)) {
//This country code already selected. Hide it
item.style.display = 'none';
}
// otherwise, hide the item
else {
} else {
// otherwise, show the item
item.style.display = 'block';
}
});

View File

@ -30,7 +30,7 @@
<i class="ui green checkmark icon"></i> Redirection Rule Deleted
</div>
<!-- Options -->
<div class="ui basic segment" style="background-color: #f7f7f7; border-radius: 1em;">
<div class="ui basic segment advanceoptions">
<div class="ui accordion advanceSettings">
<div class="title">
<i class="dropdown icon"></i>

View File

@ -50,7 +50,7 @@
</div>
</div>
<!-- Advance configs -->
<div class="ui basic segment" style="background-color: #f7f7f7; border-radius: 1em;">
<div class="ui basic segment advanceoptions">
<div id="advanceProxyRules" class="ui fluid accordion">
<div class="title">
<i class="dropdown icon"></i>

View File

@ -94,7 +94,7 @@
<label>Force redirect HTTP request to HTTPS</label>
</div>
</div>
<div class="ui basic segment" style="background-color: #f7f7f7; border-radius: 1em;">
<div class="ui basic segment advanceoptions">
<div class="ui accordion advanceSettings">
<div class="title">
<i class="dropdown icon"></i>
@ -579,7 +579,7 @@
let timestamps = [];
for(var i = 0; i < dataCount; i++){
timestamps.push(parseInt(Date.now() / 1000) + i);
timestamps.push(new Date(Date.now() + i * 1000).toLocaleString().replace(',', ''));
}
function fetchData() {
@ -600,10 +600,8 @@
txValues.shift();
}
timestamps.push(parseInt(Date.now() / 1000));
timestamps.push(new Date(Date.now()).toLocaleString().replace(',', ''));
timestamps.shift();
updateChart();
}
})

View File

@ -69,7 +69,7 @@
</div>
<!-- Advance configs -->
<div class="ui basic segment" style="background-color: #f7f7f7; border-radius: 1em;">
<div class="ui basic segment advanceoptions">
<div id="advanceProxyRules" class="ui fluid accordion">
<div class="title">
<i class="dropdown icon"></i>

330
src/web/darktheme.css Normal file
View File

@ -0,0 +1,330 @@
/*
Darktheme CSS
This file contains the CSS for the dark theme.
This will override the default CSS (white theme) for semantic UI
*/
body.darkTheme {
background-color: var(--theme_bg);
color: var(--text_color);
}
body.darkTheme h1,
body.darkTheme h2,
body.darkTheme h3,
body.darkTheme h4,
body.darkTheme h5,
body.darkTheme h6,
body.darkTheme a {
color: var(--text_color);
}
body.darkTheme .ui.header {
color: var(--text_color) !important;
}
body.darkTheme p,
body.darkTheme span{
color: var(--text_color_secondary);
}
body.darkTheme .ui.secondary.menu .dropdown.item:hover,
body.darkTheme .ui.secondary.menu .link.item:hover,
body.darkTheme .ui.secondary.menu a.item:hover {
color: var(--text_color) !important;
}
body.darkTheme .ui.basic.white.icon.button {
background-color: transparent !important;
border: none !important;
}
body.darkTheme .ui.basic.white.icon.button:hover {
border: none !important;
opacity: 0.8;
}
body.darkTheme .ui.basic.white.icon.button:disabled {
border: none !important;
opacity: 0.5;
}
body.darkTheme .ui.basic.buttons .button i.icon {
color: #ffffff !important;
}
body.darkTheme .ui.basic.button:not(.red) {
color: #ffffff !important;
border: 1px solid var(--button_border_color) !important;
}
body.darkTheme .ui.basic.button:not(.red):hover {
border: 1px solid var(--button_border_color) !important;
background-color: var(--theme_bg) !important;
opacity: 0.8;
}
body.darkTheme .ui.basic.button.red:hover {
background-color: #380a0a !important;
opacity: 0.8;
}
body.darkTheme .ui.basic.button:disabled {
border: none !important;
background-color: transparent !important;
opacity: 0.5;
}
body.darkTheme .ui.basic.button:focus,
body.darkTheme .ui.basic.buttons .button:focus {
background: transparent !important;
background-color: transparent !important;
border: none !important;
}
body.darkTheme .ui.table thead th,
body.darkTheme .ui.table tbody td,
body.darkTheme .ui.table tfoot td {
color: #ffffff !important;
}
body.darkTheme .ui.input input,
body.darkTheme .ui.input input::placeholder,
body.darkTheme .ui.input input:focus,
body.darkTheme .ui.input input:active {
color: #ffffff !important;
border-color: #ffffff !important;
}
body.darkTheme .ui.input input {
background-color: var(--theme_bg_active) !important;
border: 1px solid transparent !important;
}
body.darkTheme .ui.input input:focus,
body.darkTheme .ui.input input:active {
border-color: var(--theme_highlight) !important;
}
body.darkTheme .ui.input input::placeholder {
opacity: 0.7;
}
body.darkTheme .ui.label,
body.darkTheme .ui.label .detail,
body.darkTheme .ui.label .icon {
color: #ffffff !important;
}
body.darkTheme .advanceoptions .title {
color: var(--text_color_secondary) !important;
}
body.darkTheme .ui.toggle.checkbox input ~ .box,
body.darkTheme .ui.toggle.checkbox input ~ label,
body.darkTheme .ui.toggle.checkbox input ~ label:focus {
color: var(--text_color_secondary) !important;
}
body.darkTheme .ui.toggle.checkbox input ~ label::before{
background-color: var(--theme_bg_secondary) !important;
}
body.darkTheme .ui.toggle.checkbox input:checked ~ label::before{
background-color: var(--theme_highlight) !important;
}
body.darkTheme .ui.segment:not(.basic) {
background-color: var(--theme_bg) !important;
color: var(--text_color) !important;
border: 1px solid transparent !important;
}
body.darkTheme .sub.header {
color: var(--text_color) !important;
}
body.darkTheme .ui.radio.defaultsite.checkbox label {
color: var(--text_color) !important;
}
body.darkTheme .ui.radio.defaultsite.checkbox label small {
color: var(--text_color_secondary) !important;
}
body.darkTheme .ui.form .field input,
body.darkTheme .ui.form .field input::placeholder,
body.darkTheme .ui.form .field input:focus,
body.darkTheme .ui.form .field input:active {
color: var(--text_color) !important;
border-color: 1px solid transparent !important;
background-color: var(--theme_bg_active) !important;
}
body.darkTheme .ui.form .field input::placeholder {
opacity: 0.7;
}
body.darkTheme .ui.form .field label,
body.darkTheme .ui.form .field .ui.checkbox input:checked ~ label {
color: var(--text_color) !important;
}
body.darkTheme .ui.basic.label {
background-color: var(--theme_bg_secondary) !important;
color: var(--text_color) !important;
}
/*
HTTP Proxy Table
*/
body.darkTheme .ui.table{
background-color: transparent !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table thead th,
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td,
body.darkTheme .ui.celled.sortable.unstackable.compact.table tfoot td {
background-color: var(--theme_bg) !important;
color: var(--text_color) !important;
border-color: var(--divider_color) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table thead th {
background-color: var(--theme_bg_secondary) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody tr:hover {
background-color: var(--theme_bg_hover) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td a {
color: var(--link_color) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td a:hover {
color: var(--link_hover_color) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td small {
color: var(--text_color_secondary) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.toggle.checkbox input ~ .box,
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.toggle.checkbox input ~ label,
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.toggle.checkbox input ~ label:focus {
color: var(--text_color_secondary) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.toggle.checkbox input ~ label::before {
background-color: var(--theme_bg_secondary) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.toggle.checkbox input:checked ~ label::before {
background-color: var(--theme_highlight) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.circular.mini.basic.icon.button {
color: var(--button_color) !important;
border: 1px solid var(--button_border_color) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.circular.mini.basic.icon.button:hover {
background-color: var(--button_hover_bg) !important;
color: var(--button_hover_color) !important;
border: 1px solid var(--button_border_color) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.circular.mini.red.basic.icon.button {
color: var(--button_red_color) !important;
border: 1px solid var(--button_red_border_color) !important;
}
body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.circular.mini.red.basic.icon.button:hover {
background-color: #380a0a !important;
color: var(--button_red_hover_color) !important;
}
body.darkTheme .ui.basic.small.icon.circular.button {
color: var(--button_color) !important;
border: 1px solid var(--button_border_color) !important;
}
body.darkTheme .ui.basic.small.icon.circular.button:hover {
background-color: var(--button_hover_bg) !important;
color: var(--button_hover_color) !important;
border: 1px solid var(--button_border_color) !important;
opacity: 0.8;
}
body.darkTheme .ui.checkbox input ~ .box,
body.darkTheme .ui.checkbox input ~ label,
body.darkTheme .ui.checkbox input ~ label:focus {
color: var(--text_color_secondary) !important;
}
body.darkTheme .ui.basic.advance.segment {
background-color: var(--theme_bg) !important;
color: var(--text_color) !important;
border: 1px solid var(--divider_color) !important;
}
body.darkTheme .ui.endpointAdvanceConfig.accordion .title {
color: var(--text_color) !important;
}
/*
Virtual Directorie Table
*/
body.darkTheme .ui.fluid.search.selection.dropdown {
background-color: var(--theme_bg) !important;
color: var(--text_color) !important;
border-color: transparent !important;
}
body.darkTheme .ui.fluid.search.selection.dropdown .menu {
background-color: var(--theme_bg) !important;
color: var(--text_color) !important;
}
body.darkTheme .ui.fluid.search.selection.dropdown .menu .item {
color: var(--text_color) !important;
}
body.darkTheme .ui.selection.dropdown .menu > .item {
border-top: 1px solid var(--divider_color) !important;
}
body.darkTheme .ui.selection.active.dropdown .menu {
border-color: var(--divider_color) !important;
}
body.darkTheme .ui.fluid.search.selection.dropdown .menu .item:hover {
background-color: var(--theme_bg_hover) !important;
color: var(--text_color) !important;
}
body.darkTheme .ui.fluid.search.selection.dropdown .menu .item.active.selected {
background-color: var(--theme_highlight) !important;
color: var(--text_color) !important;
}
body.darkTheme .ui.fluid.search.selection.dropdown .search {
background-color: var(--theme_bg) !important;
color: var(--text_color) !important;
border-color: transparent !important;
}
body.darkTheme .ui.fluid.search.selection.dropdown .text {
color: var(--text_color) !important;
}
body.darkTheme .ui.fluid.search.selection.dropdown .dropdown.icon {
color: var(--text_color) !important;
}

View File

@ -16,8 +16,10 @@
<script src="script/chart.js"></script>
<script src="script/utils.js"></script>
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="darktheme.css">
</head>
<body>
<script src="script/darktheme.js"></script>
<div class="menubar">
<div class="item">
<img class="logo" src="img/logo.svg">
@ -29,9 +31,9 @@
<div class="ui right floated buttons" style="padding-top: 2px; padding-right: 0.4em;">
<button class="ui basic white icon button" onclick="logout();"><i class="sign-out icon"></i></button>
</div>
<!-- <div class="ui right floated buttons" style="padding-top: 2px;">
<div class="ui right floated buttons" style="padding-top: 2px; margin-right: 0.4em;">
<button id="themeColorButton" class="ui icon button" onclick="toggleTheme();"><i class="sun icon"></i></button>
</div> -->
</div>
</div>
<div class="wrapper">
<div class="toolbar">
@ -269,11 +271,9 @@
function toggleTheme(){
if ($("body").hasClass("darkTheme")){
$("body").removeClass("darkTheme")
$("#themeColorButton").html(`<i class="ui moon icon"></i>`);
setDarkTheme(false);
}else{
$("body").addClass("darkTheme");
$("#themeColorButton").html(`<i class="ui sun icon"></i>`);
setDarkTheme(true);
}
}

View File

@ -2,13 +2,10 @@
index.html style overwrite
*/
:root{
--theme_background: linear-gradient(60deg, rgb(84, 58, 183) 0%, rgb(0, 172, 193) 100%);
--theme_background_inverted: linear-gradient(215deg, rgba(38,60,71,1) 13%, rgba(2,3,42,1) 84%);
--theme_green: linear-gradient(270deg, #27e7ff, #00ca52);
--theme_red: linear-gradient(203deg, rgba(250,172,38,1) 17%, rgba(202,0,37,1) 78%);
}
/* Theme Color Definations */
/* Theme Color Definition */
body:not(.darkTheme){
--theme_bg: #f6f6f6;
--theme_bg_primary: #ffffff;
@ -16,7 +13,7 @@ body:not(.darkTheme){
--theme_bg_active: #ececec;
--theme_highlight: #a9d1f3;
--theme_bg_inverted: #27292d;
--theme_advance: #f8f8f9;
--theme_advance: #f7f7f7;
--item_color: #5e5d5d;
--item_color_select: rgba(0,0,0,.87);
--text_color: #414141;
@ -25,25 +22,35 @@ body:not(.darkTheme){
--text_color_inverted: #fcfcfc;
--button_text_color: #878787;
--button_border_color: #dedede;
--theme_background: linear-gradient(60deg, rgb(84, 58, 183) 0%, rgb(0, 172, 193) 100%);
--theme_background_inverted: linear-gradient(215deg, rgba(38,60,71,1) 13%, rgba(2,3,42,1) 84%);
--theme_green: linear-gradient(270deg, #27e7ff, #00ca52);
--theme_red: linear-gradient(203deg, rgba(250,172,38,1) 17%, rgba(202,0,37,1) 78%);
}
body.darkTheme{
--theme_bg: #27292d;
--theme_bg_primary: #3d3f47;
--theme_bg_secondary: #373a42;
--theme_highlight: #6682c4;
--theme_bg_active: #292929;
--theme_bg: #000000;
--theme_bg_primary: #141414;
--theme_bg_secondary:#230046;
--theme_highlight: #320064;
--theme_bg_active: #020101;
--theme_bg_inverted: #f8f8f9;
--theme_advance: #333333;
--theme_advance: #000000;
--item_color: #cacaca;
--text_color: #fcfcfc;
--text_color_secondary: #dfdfdf;
--text_color: #eef1f3;
--text_color_secondary: #b5c0c7;
--input_color: black;
--divider_color: #3b3b3b;
--divider_color: #282828;
--item_color_select: rgba(255, 255, 255, 0.87);
--text_color_inverted: #414141;
--button_text_color: #e9e9e9;
--button_border_color: #646464;
--theme_background: linear-gradient(214deg, rgba(3,1,70,1) 17%, rgba(60,1,80,1) 78%);
--theme_background_inverted: linear-gradient(215deg, rgba(38,60,71,1) 13%, rgba(2,3,42,1) 84%);
--theme_green: linear-gradient(214deg, rgba(25,128,94,1) 17%, rgba(62,76,111,1) 78%);
--theme_red: linear-gradient(203deg, rgba(250,172,38,1) 17%, rgba(202,0,37,1) 78%);
}
/* Theme Toggle CSS */
@ -368,7 +375,7 @@ body{
}
.basic.segment.advanceoptions{
background-color: #f7f7f7;
background-color: var(--theme_advance);
border-radius: 1em;
}

View File

@ -0,0 +1,51 @@
/*
Dark Theme Toggle Manager
This script is used to manage the dark theme toggle button in the header of the website.
It will change the theme of the website to dark mode when the toggle is clicked and back to light mode when clicked again.
Must be included just after the start of body tag in the HTML file.
*/
function _whiteThemeHandleApplyChange(){
$(".menubar .logo").attr("src", "img/logo.svg");
}
function _darkThemeHandleApplyChange(){
$(".menubar .logo").attr("src", "img/logo_white.svg");
}
//Check if the theme is dark, must be done before the body is loaded to prevent flickering
function setDarkTheme(isDarkTheme = false){
if (isDarkTheme){
$("body").addClass("darkTheme");
$("#themeColorButton").html(`<i class="ui sun icon"></i>`);
localStorage.setItem("theme", "dark");
//Check if the page is still loading, if not change the logo
if (document.readyState == "complete"){
_darkThemeHandleApplyChange();
}else{
//Wait for the page to load and then change the logo
$(document).ready(function(){
_darkThemeHandleApplyChange();
});
}
}else{
$("body").removeClass("darkTheme")
$("#themeColorButton").html(`<i class="ui moon icon"></i>`);
localStorage.setItem("theme", "light");
//By default the page is white theme. So no need to change the logo if page is still loading
if (document.readyState == "complete"){
//Switching back to light theme
_whiteThemeHandleApplyChange();
}
}
}
if (localStorage.getItem("theme") == "dark"){
setDarkTheme(true);
}else{
setDarkTheme(false);
}

View File

@ -50,7 +50,7 @@
</div>
<small>If you don't want to share your private email address, you can also fill in an email address that point to a mailbox not exists on your domain.</small>
</div>
<div class="ui basic segment" style="background-color: #f7f7f7; border-radius: 1em;">
<div class="ui basic segment advanceoptions">
<div class="ui accordion advanceSettings">
<div class="title">
<i class="dropdown icon"></i>
@ -437,11 +437,15 @@
let optionalFieldsHTML = "";
for (const [key, datatype] of Object.entries(data)) {
if (datatype == "int"){
$("#dnsProviderAPIFields").append(`<div class="ui fluid labeled dnsConfigField input" key="${key}" style="margin-top: 0.2em;">
let defaultValue = 10;
if (key == "HTTPTimeout"){
defaultValue = 300;
}
$("#dnsProviderAPIFields").append(`<div class="ui fluid labeled dnsConfigField input typeint" key="${key}" style="margin-top: 0.2em;">
<div class="ui basic blue label" style="font-weight: 300;">
${key}
</div>
<input type="number" value="300">
<input type="number" value="${defaultValue}">
</div>`);
}else if (datatype == "bool"){
booleanFieldsHTML += (`<div class="ui checkbox dnsConfigField" key="${key}" style="margin-top: 1em !important; padding-left: 0.4em;">
@ -600,8 +604,12 @@
//Boolean option
let checked = $(this).find("input")[0].checked;
dnsCredentials[thisKey] = checked;
}else if ($(this).hasClass("typeint")){
//Int options
let value = $(this).find("input").val();
dnsCredentials[thisKey] = parseInt(value);
}else{
//String or int options
//String options
let value = $(this).find("input").val().trim();
dnsCredentials[thisKey] = value;
}

View File

@ -86,7 +86,7 @@
</div>
</div>
<div class="ui divider"></div>
<div class="ui basic segment" style="background-color: #f7f7f7; border-radius: 1em;">
<div class="ui basic segment advanceoptions">
<div class="ui fluid accordion">
<div class="title">
<i class="dropdown icon" tabindex="0"><div class="menu" tabindex="-1"></div></i>

View File

@ -6,7 +6,7 @@
*/
/*
Color definations
Color definition
*/
:root{
--dark_theme_toggle: #333333;