Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom css feature for the WebUi #13415

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/base/preferences.cpp
Expand Up @@ -738,6 +738,26 @@ void Preferences::setWebUiRootFolder(const QString &path)
setValue("Preferences/WebUI/RootFolder", path);
}

bool Preferences::isWebUICustomCssEnabled() const
{
return value("Preferences/WebUI/CustomCssEnabled", false).toBool();
}

void Preferences::setWebUICustomCssEnabled(const bool enabled)
{
setValue("Preferences/WebUI/CustomCssEnabled", enabled);
}

QString Preferences::getWebUICustomCss() const
{
return value("Preferences/WebUI/CustomCss").toString();
}

void Preferences::setWebUICustomCss(const QString &css)
{
setValue("Preferences/WebUI/CustomCss", css);
}

bool Preferences::isWebUICustomHTTPHeadersEnabled() const
{
return value("Preferences/WebUI/CustomHTTPHeadersEnabled", false).toBool();
Expand Down
6 changes: 6 additions & 0 deletions src/base/preferences.h
Expand Up @@ -223,6 +223,12 @@ class Preferences : public QObject
QString getWebUiRootFolder() const;
void setWebUiRootFolder(const QString &path);

// WebUI custom stylesheet
bool isWebUICustomCssEnabled() const;
void setWebUICustomCssEnabled(bool enabled);
QString getWebUICustomCss() const;
void setWebUICustomCss(const QString &css);

// WebUI custom HTTP headers
bool isWebUICustomHTTPHeadersEnabled() const;
void setWebUICustomHTTPHeadersEnabled(bool enabled);
Expand Down
8 changes: 8 additions & 0 deletions src/gui/optionsdialog.cpp
Expand Up @@ -503,6 +503,8 @@ OptionsDialog::OptionsDialog(QWidget *parent)
connect(m_ui->DNSPasswordTxt, &QLineEdit::textChanged, this, &ThisType::enableApplyButton);
connect(m_ui->groupAltWebUI, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
connect(m_ui->textWebUIRootFolder, &FileSystemPathLineEdit::selectedPathChanged, this, &ThisType::enableApplyButton);
connect(m_ui->groupWebUIAddCustomCss, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
connect(m_ui->textWebUICustomCss, &QPlainTextEdit::textChanged, this, &OptionsDialog::enableApplyButton);
connect(m_ui->groupWebUIAddCustomHTTPHeaders, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
connect(m_ui->textWebUICustomHTTPHeaders, &QPlainTextEdit::textChanged, this, &OptionsDialog::enableApplyButton);
#endif // DISABLE_WEBUI
Expand Down Expand Up @@ -864,6 +866,9 @@ void OptionsDialog::saveOptions()
// Alternative UI
pref->setAltWebUiEnabled(m_ui->groupAltWebUI->isChecked());
pref->setWebUiRootFolder(m_ui->textWebUIRootFolder->selectedPath());
// Custom Css
pref->setWebUICustomCssEnabled(m_ui->groupWebUIAddCustomCss->isChecked());
pref->setWebUICustomCss(m_ui->textWebUICustomCss->toPlainText());
// Custom HTTP headers
pref->setWebUICustomHTTPHeadersEnabled(m_ui->groupWebUIAddCustomHTTPHeaders->isChecked());
pref->setWebUICustomHTTPHeaders(m_ui->textWebUICustomHTTPHeaders->toPlainText());
Expand Down Expand Up @@ -1247,6 +1252,9 @@ void OptionsDialog::loadOptions()

m_ui->groupAltWebUI->setChecked(pref->isAltWebUiEnabled());
m_ui->textWebUIRootFolder->setSelectedPath(pref->getWebUiRootFolder());
// Custom Css
m_ui->groupWebUIAddCustomCss->setChecked(pref->isWebUICustomCssEnabled());
m_ui->textWebUICustomCss->setPlainText(pref->getWebUICustomCss());
// Custom HTTP headers
m_ui->groupWebUIAddCustomHTTPHeaders->setChecked(pref->isWebUICustomHTTPHeadersEnabled());
m_ui->textWebUICustomHTTPHeaders->setPlainText(pref->getWebUICustomHTTPHeaders());
Expand Down
15 changes: 15 additions & 0 deletions src/gui/optionsdialog.ui
Expand Up @@ -3156,6 +3156,21 @@ Specify an IPv4 or IPv6 address. You can specify "0.0.0.0" for any IPv
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupWebUIAddCustomCss">
<property name="title">
<string>Add custom css</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_36">
<item>
<widget class="QPlainTextEdit" name="textWebUICustomCss"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
Expand Down
8 changes: 8 additions & 0 deletions src/webui/api/appcontroller.cpp
Expand Up @@ -238,6 +238,9 @@ void AppController::preferencesAction()
// Use alternative Web UI
data["alternative_webui_enabled"] = pref->isAltWebUiEnabled();
data["alternative_webui_path"] = pref->getWebUiRootFolder();
// Custom Css
data["web_ui_custom_css_enabled"] = pref->isWebUICustomCssEnabled();
data["web_ui_custom_css"] = pref->getWebUICustomCss();
// Security
data["web_ui_clickjacking_protection_enabled"] = pref->isWebUiClickjackingProtectionEnabled();
data["web_ui_csrf_protection_enabled"] = pref->isWebUiCSRFProtectionEnabled();
Expand Down Expand Up @@ -625,6 +628,11 @@ void AppController::setPreferencesAction()
pref->setAltWebUiEnabled(it.value().toBool());
if (hasKey("alternative_webui_path"))
pref->setWebUiRootFolder(it.value().toString());
// Custom Css
if (hasKey("web_ui_custom_css_enabled"))
pref->setWebUICustomCssEnabled(it.value().toBool());
if (hasKey("web_ui_custom_css"))
pref->setWebUICustomCss(it.value().toString());
// Security
if (hasKey("web_ui_clickjacking_protection_enabled"))
pref->setWebUiClickjackingProtectionEnabled(it.value().toBool());
Expand Down
12 changes: 12 additions & 0 deletions src/webui/webapplication.cpp
Expand Up @@ -225,6 +225,10 @@ void WebApplication::translateDocument(QString &data) const

data.replace(QLatin1String("${LANG}"), m_currentLocale.left(2));
data.replace(QLatin1String("${CACHEID}"), m_cacheID);

QString customCss = m_isCustomCssEnabled ? m_customCss : "";
customCss.replace('<', "&lt;");
data.replace(QLatin1String("${CUSTOMCSS}"), customCss);
}
}

Expand Down Expand Up @@ -328,6 +332,14 @@ void WebApplication::configure()
}
}

const bool newIsCustomCssEnabled = pref->isWebUICustomCssEnabled();
const QString newCustomCss = pref->getWebUICustomCss();
if (m_isCustomCssEnabled != newIsCustomCssEnabled || m_customCss != newCustomCss) {
m_translatedFiles.clear();
}
m_isCustomCssEnabled = newIsCustomCssEnabled;
m_customCss = newCustomCss;

m_isLocalAuthEnabled = pref->isWebUiLocalAuthEnabled();
m_isAuthSubnetWhitelistEnabled = pref->isWebUiAuthSubnetWhitelistEnabled();
m_authSubnetWhitelist = pref->getWebUiAuthSubnetWhitelist();
Expand Down
2 changes: 2 additions & 0 deletions src/webui/webapplication.h
Expand Up @@ -132,6 +132,8 @@ class WebApplication final
QSet<QString> m_publicAPIs;
bool m_isAltUIUsed = false;
QString m_rootFolder;
bool m_isCustomCssEnabled = false;
QString m_customCss;

struct TranslatedFile
{
Expand Down
1 change: 1 addition & 0 deletions src/webui/www/private/index.html
Expand Up @@ -17,6 +17,7 @@
<noscript>
<link rel="stylesheet" type="text/css" href="css/noscript.css?v=${CACHEID}" />
</noscript>
<style>${CUSTOMCSS}</style>
<script src="scripts/lib/mootools-1.2-core-yc.js"></script>
<script src="scripts/lib/mootools-1.2-more.js"></script>
<script src="scripts/lib/mocha-0.9.6-yc.js"></script>
Expand Down
23 changes: 23 additions & 0 deletions src/webui/www/private/views/preferences.html
Expand Up @@ -803,6 +803,14 @@
</div>
</fieldset>

<fieldset class="settings">
<legend>
<input type="checkbox" id="webUICustomCssCheckbox" onclick="qBittorrent.Preferences.updateWebUICustomCssSettings();" />
<label for="webUICustomCssCheckbox">QBT_TR(Add custom css)QBT_TR[CONTEXT=OptionsDialog]</label>
</legend>
<textarea id="webUICustomCssTextarea" style="width: 90%;"></textarea>
</fieldset>

<fieldset class="settings">
<legend>QBT_TR(Security)QBT_TR[CONTEXT=OptionsDialog]</legend>
<div class="formRow">
Expand Down Expand Up @@ -1234,6 +1242,7 @@
updateHttpsSettings: updateHttpsSettings,
updateBypasssAuthSettings: updateBypasssAuthSettings,
updateAlternativeWebUISettings: updateAlternativeWebUISettings,
updateWebUICustomCssSettings: updateWebUICustomCssSettings,
updateHostHeaderValidationSettings: updateHostHeaderValidationSettings,
updateWebUICustomHTTPHeadersSettings: updateWebUICustomHTTPHeadersSettings,
updateDynDnsSettings: updateDynDnsSettings,
Expand Down Expand Up @@ -1473,6 +1482,11 @@
$('webui_files_location_textarea').setProperty('disabled', !isUseAlternativeWebUIEnabled);
};

const updateWebUICustomCssSettings = function() {
const isEnabled = $('webUICustomCssCheckbox').getProperty('checked');
$('webUICustomCssTextarea').setProperty('disabled', !isEnabled);
};

const updateHostHeaderValidationSettings = function() {
const isHostHeaderValidationEnabled = $('host_header_validation_checkbox').getProperty('checked');
$('webui_domain_textarea').setProperty('disabled', !isHostHeaderValidationEnabled);
Expand Down Expand Up @@ -1834,6 +1848,11 @@
$('webui_files_location_textarea').setProperty('value', pref.alternative_webui_path);
updateAlternativeWebUISettings();

// Custom Css
$('webUICustomCssCheckbox').setProperty('checked', pref.web_ui_custom_css_enabled);
$('webUICustomCssTextarea').setProperty('value', pref.web_ui_custom_css);
updateWebUICustomCssSettings();

// Security
$('clickjacking_protection_checkbox').setProperty('checked', pref.web_ui_clickjacking_protection_enabled);
$('csrf_protection_checkbox').setProperty('checked', pref.web_ui_csrf_protection_enabled);
Expand Down Expand Up @@ -2221,6 +2240,10 @@
settings.set('alternative_webui_enabled', alternative_webui_enabled);
settings.set('alternative_webui_path', webui_files_location_textarea);

// Custom Css
settings.set('web_ui_custom_css_enabled', $('webUICustomCssCheckbox').getProperty('checked'));
settings.set('web_ui_custom_css', $('webUICustomCssTextarea').getProperty('value'));

// Security
settings.set('web_ui_clickjacking_protection_enabled', $('clickjacking_protection_checkbox').getProperty('checked'));
settings.set('web_ui_csrf_protection_enabled', $('csrf_protection_checkbox').getProperty('checked'));
Expand Down
1 change: 1 addition & 0 deletions src/webui/www/public/index.html
Expand Up @@ -10,6 +10,7 @@
<noscript>
<link rel="stylesheet" type="text/css" href="css/noscript.css?v=${CACHEID}" />
</noscript>
<style>${CUSTOMCSS}</style>
<script src="scripts/login.js?locale=${LANG}&v=${CACHEID}"></script>
</head>

Expand Down