mirror of
https://github.com/hkalexling/Mango.git
synced 2025-08-02 19:05:32 -04:00
Support 'System' theme setting (#91)
This commit is contained in:
parent
6acfa02314
commit
87b72fbd30
@ -30,18 +30,18 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uk-list li {
|
.uk-list li:not(.nopointer) {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reader-bg {
|
|
||||||
background-color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
#scan-status {
|
#scan-status {
|
||||||
cursor: auto;
|
cursor: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reader-bg {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
.break-word {
|
.break-word {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
var scanning = false;
|
let scanning = false;
|
||||||
function scan() {
|
|
||||||
|
const scan = () => {
|
||||||
scanning = true;
|
scanning = true;
|
||||||
$('#scan-status > div').removeAttr('hidden');
|
$('#scan-status > div').removeAttr('hidden');
|
||||||
$('#scan-status > span').attr('hidden', '');
|
$('#scan-status > span').attr('hidden', '');
|
||||||
var color = $('#scan').css('color');
|
const color = $('#scan').css('color');
|
||||||
$('#scan').css('color', 'gray');
|
$('#scan').css('color', 'gray');
|
||||||
$.post(base_url + 'api/admin/scan', function (data) {
|
$.post(base_url + 'api/admin/scan', (data) => {
|
||||||
var ms = data.milliseconds;
|
const ms = data.milliseconds;
|
||||||
var titles = data.titles;
|
const titles = data.titles;
|
||||||
$('#scan-status > span').text('Scanned ' + titles + ' titles in ' + ms + 'ms');
|
$('#scan-status > span').text('Scanned ' + titles + ' titles in ' + ms + 'ms');
|
||||||
$('#scan-status > span').removeAttr('hidden');
|
$('#scan-status > span').removeAttr('hidden');
|
||||||
$('#scan').css('color', color);
|
$('#scan').css('color', color);
|
||||||
@ -15,11 +16,25 @@ function scan() {
|
|||||||
scanning = false;
|
scanning = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
$(function() {
|
|
||||||
$('li').click(function() {
|
String.prototype.capitalize = function() {
|
||||||
url = $(this).attr('data-url');
|
return this.charAt(0).toUpperCase() + this.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
$('li').click((e) => {
|
||||||
|
const url = $(e.currentTarget).attr('data-url');
|
||||||
if (url) {
|
if (url) {
|
||||||
$(location).attr('href', url);
|
$(location).attr('href', url);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const setting = loadThemeSetting();
|
||||||
|
$('#theme-select').val(setting.capitalize());
|
||||||
|
|
||||||
|
$('#theme-select').change((e) => {
|
||||||
|
const newSetting = $(e.currentTarget).val().toLowerCase();
|
||||||
|
saveThemeSetting(newSetting);
|
||||||
|
setTheme();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -34,7 +34,9 @@ const download = () => {
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: base_url + 'api/admin/mangadex/download',
|
url: base_url + 'api/admin/mangadex/download',
|
||||||
data: JSON.stringify({chapters: chapters}),
|
data: JSON.stringify({
|
||||||
|
chapters: chapters
|
||||||
|
}),
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
dataType: 'json'
|
dataType: 'json'
|
||||||
})
|
})
|
||||||
@ -66,8 +68,7 @@ const toggleSpinner = () => {
|
|||||||
if (attr) {
|
if (attr) {
|
||||||
$('#spinner').removeAttr('hidden');
|
$('#spinner').removeAttr('hidden');
|
||||||
$('#search-btn').attr('hidden', '');
|
$('#search-btn').attr('hidden', '');
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$('#search-btn').removeAttr('hidden');
|
$('#search-btn').removeAttr('hidden');
|
||||||
$('#spinner').attr('hidden', '');
|
$('#spinner').attr('hidden', '');
|
||||||
}
|
}
|
||||||
@ -98,8 +99,7 @@ const search = () => {
|
|||||||
const path = new URL(input).pathname;
|
const path = new URL(input).pathname;
|
||||||
const match = /\/title\/([0-9]+)/.exec(path);
|
const match = /\/title\/([0-9]+)/.exec(path);
|
||||||
int_id = parseInt(match[1]);
|
int_id = parseInt(match[1]);
|
||||||
}
|
} catch (e) {
|
||||||
catch(e) {
|
|
||||||
int_id = parseInt(input);
|
int_id = parseInt(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,8 +139,12 @@ const search = () => {
|
|||||||
const comp = (a, b) => {
|
const comp = (a, b) => {
|
||||||
var ai;
|
var ai;
|
||||||
var bi;
|
var bi;
|
||||||
try {ai = parseFloat(a);} catch(e) {}
|
try {
|
||||||
try {bi = parseFloat(b);} catch(e) {}
|
ai = parseFloat(a);
|
||||||
|
} catch (e) {}
|
||||||
|
try {
|
||||||
|
bi = parseFloat(b);
|
||||||
|
} catch (e) {}
|
||||||
if (typeof ai === 'undefined') return -1;
|
if (typeof ai === 'undefined') return -1;
|
||||||
if (typeof bi === 'undefined') return 1;
|
if (typeof bi === 'undefined') return 1;
|
||||||
if (ai < bi) return 1;
|
if (ai < bi) return 1;
|
||||||
@ -176,8 +180,7 @@ const parseRange = str => {
|
|||||||
if (!matches) {
|
if (!matches) {
|
||||||
alert('danger', `Failed to parse filter input ${str}`);
|
alert('danger', `Failed to parse filter input ${str}`);
|
||||||
return [null, null];
|
return [null, null];
|
||||||
}
|
} else if (typeof matches[1] !== 'undefined' && typeof matches[2] !== 'undefined') {
|
||||||
else if (typeof matches[1] !== 'undefined' && typeof matches[2] !== 'undefined') {
|
|
||||||
// e.g., <= 30
|
// e.g., <= 30
|
||||||
num = parseInt(matches[2]);
|
num = parseInt(matches[2]);
|
||||||
if (isNaN(num)) {
|
if (isNaN(num)) {
|
||||||
@ -194,8 +197,7 @@ const parseRange = str => {
|
|||||||
case '>=':
|
case '>=':
|
||||||
return [num, null];
|
return [num, null];
|
||||||
}
|
}
|
||||||
}
|
} else if (typeof matches[3] !== 'undefined') {
|
||||||
else if (typeof matches[3] !== 'undefined') {
|
|
||||||
// a single number
|
// a single number
|
||||||
num = parseInt(matches[3]);
|
num = parseInt(matches[3]);
|
||||||
if (isNaN(num)) {
|
if (isNaN(num)) {
|
||||||
@ -203,8 +205,7 @@ const parseRange = str => {
|
|||||||
return [null, null];
|
return [null, null];
|
||||||
}
|
}
|
||||||
return [num, num];
|
return [num, num];
|
||||||
}
|
} else if (typeof matches[4] !== 'undefined' && typeof matches[5] !== 'undefined') {
|
||||||
else if (typeof matches[4] !== 'undefined' && typeof matches[5] !== 'undefined') {
|
|
||||||
// e.g., 10 - 23
|
// e.g., 10 - 23
|
||||||
num = parseInt(matches[4]);
|
num = parseInt(matches[4]);
|
||||||
const n2 = parseInt(matches[5]);
|
const n2 = parseInt(matches[5]);
|
||||||
@ -213,8 +214,7 @@ const parseRange = str => {
|
|||||||
return [null, null];
|
return [null, null];
|
||||||
}
|
}
|
||||||
return [num, n2];
|
return [num, n2];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// empty or space only
|
// empty or space only
|
||||||
return [null, null];
|
return [null, null];
|
||||||
}
|
}
|
||||||
@ -280,7 +280,7 @@ const buildTable = () => {
|
|||||||
const group_str = Object.entries(chp.groups).map(([k, v]) => {
|
const group_str = Object.entries(chp.groups).map(([k, v]) => {
|
||||||
return `<a href="${baseURL }/group/${v}">${k}</a>`;
|
return `<a href="${baseURL }/group/${v}">${k}</a>`;
|
||||||
}).join(' | ');
|
}).join(' | ');
|
||||||
const dark = getTheme() === 'dark' ? 'dark' : '';
|
const dark = loadTheme() === 'dark' ? 'dark' : '';
|
||||||
return `<tr class="ui-widget-content ${dark}">
|
return `<tr class="ui-widget-content ${dark}">
|
||||||
<td><a href="${baseURL}/chapter/${chp.id}">${chp.id}</a></td>
|
<td><a href="${baseURL}/chapter/${chp.id}">${chp.id}</a></td>
|
||||||
<td>${chp.title}</td>
|
<td>${chp.title}</td>
|
||||||
|
@ -1,22 +1,44 @@
|
|||||||
const getTheme = () => {
|
// https://flaviocopes.com/javascript-detect-dark-mode/
|
||||||
var theme = localStorage.getItem('theme');
|
const preferDarkMode = () => {
|
||||||
if (!theme) theme = 'light';
|
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
return theme;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveTheme = theme => {
|
const validThemeSetting = (theme) => {
|
||||||
localStorage.setItem('theme', theme);
|
return ['dark', 'light', 'system'].indexOf(theme) >= 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// dark / light / system
|
||||||
|
const loadThemeSetting = () => {
|
||||||
|
let str = localStorage.getItem('theme');
|
||||||
|
if (!str || !validThemeSetting(str)) str = 'light';
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
|
||||||
|
// dark / light
|
||||||
|
const loadTheme = () => {
|
||||||
|
let setting = loadThemeSetting();
|
||||||
|
if (setting === 'system') {
|
||||||
|
setting = preferDarkMode() ? 'dark' : 'light';
|
||||||
|
}
|
||||||
|
return setting;
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveThemeSetting = setting => {
|
||||||
|
if (!validThemeSetting(setting)) setting = 'light';
|
||||||
|
localStorage.setItem('theme', setting);
|
||||||
|
};
|
||||||
|
|
||||||
|
// when toggled, Auto will be changed to light or dark
|
||||||
const toggleTheme = () => {
|
const toggleTheme = () => {
|
||||||
const theme = getTheme();
|
const theme = loadTheme();
|
||||||
const newTheme = theme === 'dark' ? 'light' : 'dark';
|
const newTheme = theme === 'dark' ? 'light' : 'dark';
|
||||||
|
saveThemeSetting(newTheme);
|
||||||
setTheme(newTheme);
|
setTheme(newTheme);
|
||||||
saveTheme(newTheme);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const setTheme = themeStr => {
|
const setTheme = (theme) => {
|
||||||
if (themeStr === 'dark') {
|
if (!theme) theme = loadTheme();
|
||||||
|
if (theme === 'dark') {
|
||||||
$('html').css('background', 'rgb(20, 20, 20)');
|
$('html').css('background', 'rgb(20, 20, 20)');
|
||||||
$('body').addClass('uk-light');
|
$('body').addClass('uk-light');
|
||||||
$('.uk-card').addClass('uk-card-secondary');
|
$('.uk-card').addClass('uk-card-secondary');
|
||||||
@ -32,7 +54,7 @@ const setTheme = themeStr => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const styleModal = () => {
|
const styleModal = () => {
|
||||||
const color = getTheme() === 'dark' ? '#222' : '';
|
const color = loadTheme() === 'dark' ? '#222' : '';
|
||||||
$('.uk-modal-header').css('background', color);
|
$('.uk-modal-header').css('background', color);
|
||||||
$('.uk-modal-body').css('background', color);
|
$('.uk-modal-body').css('background', color);
|
||||||
$('.uk-modal-footer').css('background', color);
|
$('.uk-modal-footer').css('background', color);
|
||||||
@ -40,9 +62,18 @@ const styleModal = () => {
|
|||||||
|
|
||||||
// do it before document is ready to prevent the initial flash of white on
|
// do it before document is ready to prevent the initial flash of white on
|
||||||
// most pages
|
// most pages
|
||||||
setTheme(getTheme());
|
setTheme();
|
||||||
|
|
||||||
$(() => {
|
$(() => {
|
||||||
// hack for the reader page
|
// hack for the reader page
|
||||||
setTheme(getTheme());
|
setTheme();
|
||||||
|
|
||||||
|
// on system dark mode setting change
|
||||||
|
if (window.matchMedia) {
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
|
.addEventListener('change', event => {
|
||||||
|
if (loadThemeSetting() === 'system')
|
||||||
|
setTheme(event.matches ? 'dark' : 'light');
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
@ -7,6 +7,14 @@
|
|||||||
<span hidden></span>
|
<span hidden></span>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nopointer">
|
||||||
|
<span>Theme</span>
|
||||||
|
<select id="theme-select" class="uk-select uk-align-right uk-width-1-3@m uk-width-1-2">
|
||||||
|
<option>Dark</option>
|
||||||
|
<option>Light</option>
|
||||||
|
<option>System</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
<li data-url="<%= base_url %>admin/downloads">Download Manager</li>
|
<li data-url="<%= base_url %>admin/downloads">Download Manager</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
setTheme(getTheme());
|
setTheme();
|
||||||
const base_url = "<%= base_url %>";
|
const base_url = "<%= base_url %>";
|
||||||
</script>
|
</script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/js/uikit.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/js/uikit.min.js"></script>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
setTheme(getTheme());
|
setTheme();
|
||||||
</script>
|
</script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/js/uikit.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/js/uikit.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/js/uikit-icons.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/uikit@3.3.1/dist/js/uikit-icons.min.js"></script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user