1
0
mirror of synced 2025-12-11 00:48:21 +08:00

feat(settings): use luna setting

This commit is contained in:
redhoodsu
2023-01-18 18:40:29 +08:00
parent 69dd37a6d2
commit 5390fd0f26
10 changed files with 142 additions and 441 deletions

View File

@@ -286,17 +286,6 @@ Add range to input a number.
|desc |string|Option description|
|option|object|Min, max, step |
### color
Add color to select a color.
|Name |Type |Desc |
|-------|------|------------------|
|cfg |object|Config object |
|name |string|Option name |
|desc |string|Option description|
|[color]|array |Color list |
### separator
Add a separator.

8
eruda.d.ts vendored
View File

@@ -344,14 +344,6 @@ declare module 'eruda' {
desc: string,
options?: SettingsRangeOptions
): void
/**
* Add color to select a color
* @param cfg Config object
* @param name Option name
* @param desc Option description
* @param colors Color list
*/
color(cfg: object, name: string, desc: string, colors: string[]): void
/**
* Add a separator
*/

View File

@@ -69,6 +69,7 @@
"luna-modal": "^1.0.0",
"luna-notification": "^0.1.4",
"luna-object-viewer": "^0.2.4",
"luna-setting": "^0.3.0",
"luna-tab": "^0.1.2",
"luna-text-viewer": "^0.2.1",
"node-sass": "^7.0.1",

View File

@@ -11,12 +11,14 @@ import $ from 'licia/$'
import toNum from 'licia/toNum'
import isDarkMode from 'licia/isDarkMode'
import extend from 'licia/extend'
import isStr from 'licia/isStr'
import startWith from 'licia/startWith'
import evalCss from '../lib/evalCss'
import { isDarkTheme } from '../lib/themes'
import LunaNotification from 'luna-notification'
import LunaModal from 'luna-modal'
import LunaTab from 'luna-tab'
import { classPrefix as c, drag, eventClient } from '../lib/util'
import { classPrefix as c, drag, eventClient, safeStorage } from '../lib/util'
export default class DevTools extends Emitter {
constructor($container, { defaults = {} } = {}) {
@@ -195,6 +197,23 @@ export default class DevTools extends Emitter {
max: 100,
step: 1,
})
.button('Restore defaults and reload', function () {
const store = safeStorage('local')
const data = JSON.parse(JSON.stringify(store))
console.log(data)
each(data, (val, key) => {
if (!isStr(val)) {
return
}
if (startWith(key, 'eruda')) {
store.removeItem(key)
}
})
window.location.reload()
})
.separator()
}
notify(content, options) {

View File

@@ -160,9 +160,7 @@ export default class EntryBtn extends Emitter {
pos: this._getDefPos(),
}))
settings
.separator()
.switch(cfg, 'rememberPos', 'Remember Entry Button Position')
settings.switch(cfg, 'rememberPos', 'Remember Entry Button Position')
this._resetPos()
}

View File

@@ -5,11 +5,10 @@ import uniqId from 'licia/uniqId'
import each from 'licia/each'
import filter from 'licia/filter'
import isStr from 'licia/isStr'
import contain from 'licia/contain'
import clone from 'licia/clone'
import escape from 'licia/escape'
import map from 'licia/map'
import evalCss from '../lib/evalCss'
import { classPrefix as c } from '../lib/util'
import LunaSetting from 'luna-setting'
export default class Settings extends Tool {
constructor() {
@@ -23,18 +22,20 @@ export default class Settings extends Tool {
init($el) {
super.init($el)
this._setting = new LunaSetting($el.get(0))
this._bindEvent()
}
remove(config, key) {
if (isStr(config)) {
this._$el.find('.eruda-text').each(function () {
this._$el.find('.luna-setting-item-title').each(function () {
const $this = $(this)
if ($this.text() === config) $this.remove()
})
} else {
this._settings = filter(this._settings, (setting) => {
if (setting.config === config && setting.key === key) {
this._$el.find('#' + setting.id).remove()
setting.item.detach()
return false
}
@@ -47,123 +48,64 @@ export default class Settings extends Tool {
return this
}
destroy() {
this._setting.destroy()
super.destroy()
evalCss.remove(this._style)
}
clear() {
this._settings = []
this._$el.html('')
this._setting.clear()
}
switch(config, key, desc) {
const id = this._genId('settings')
this._settings.push({ config, key, id })
const checked = config.get(key) ? 'checked' : ''
// prettier-ignore
const html = `<div id="${escape(id)}" class="${c('switch')}">
${escape(desc)}
<label class="${c('checkbox')}">
<input type="checkbox" class="${c('input')}" data-id="${escape(id)}" ${checked}>
<span class="${c('label')}"></span>
<span class="${c('handle')}"></span>
</label>
</div>`
this._$el.append(html)
return this
}
color(
config,
key,
desc,
colors = ['#2196f3', '#707d8b', '#f44336', '#009688', '#ffc107']
) {
const id = this._genId('settings')
this._settings.push({ config, key, id })
const colorsHtml = map(
colors,
(color) => `<li style="background: ${escape(color)};"></li>`
).join('')
// prettier-ignore
const html = `<div id="${escape(id)}" class="${c('color')}">
<div class="${c('head')}">
${escape(desc)}
<span class="${c('val')}" style="background-color: ${escape(config.get(key))};"></span>
</div>
<ul data-id="${escape(id)}">
${colorsHtml}
</ul>
</div>`
this._$el.append(html)
const item = this._setting.appendCheckbox(id, !!config.get(key), desc)
this._settings.push({ config, key, id, item })
return this
}
select(config, key, desc, selections) {
const id = this._genId('settings')
this._settings.push({ config, key, id })
const selectionsHtml = map(
selections,
(selection) => `<li>${escape(selection)}</li>`
).join('')
const html = `<div id="${escape(id)}" class="${c('select')}">
<div class="${c('head')}">
${escape(desc)}
<span class="${c('val')}">${escape(config.get(key))}</span>
</div>
<ul data-id="${escape(id)}">
${selectionsHtml}
</ul>
</div>`
this._$el.append(html)
const selectOptions = {}
each(selections, (selection) => (selectOptions[selection] = selection))
const item = this._setting.appendSelect(
id,
config.get(key),
'',
desc,
selectOptions
)
this._settings.push({ config, key, id, item })
return this
}
range(config, key, desc, { min = 0, max = 1, step = 0.1 }) {
const id = this._genId('settings')
this._settings.push({ config, key, min, max, step, id })
const item = this._setting.appendNumber(id, config.get(key), desc, {
max,
min,
step,
range: true,
})
this._settings.push({ config, key, min, max, step, id, item })
const val = config.get(key)
// prettier-ignore
const html = `<div id="${escape(id)}" class="${c('range')}">
<div class="${c('head')}">
${escape(desc)}
<span class="${c('val')}">${val}</span>
</div>
<div class="${c('input-container')}" data-id="${escape(id)}">
<div class="${c('range-track')}">
<div class="${c('range-track-bar')}">
<div class="${c('range-track-progress')}" style="width: ${progress(val, min, max)}%;"></div>
</div>
</div>
<input type="range" min="${min}" max="${max}" step="${step}" value="${val}"/>
</div>
</div>`
this._$el.append(html)
return this
}
button(text, handler) {
this._setting.appendButton(text, handler)
return this
}
separator() {
this._$el.append('<div class="eruda-separator"></div>')
this._setting.appendSeparator()
return this
}
text(text) {
this._$el.append(`<div class="eruda-text">${text}</div>`)
this._setting.appendTitle(text)
return this
}
@@ -172,7 +114,7 @@ export default class Settings extends Tool {
const children = clone(this._$el.get(0).children)
function isSeparator(node) {
return node.getAttribute('class') === 'eruda-separator'
return contain(node.getAttribute('class'), 'luna-setting-item-separator')
}
for (let i = 0, len = children.length; i < len - 1; i++) {
@@ -184,9 +126,6 @@ export default class Settings extends Tool {
_genId() {
return uniqId('eruda-settings')
}
_closeAll() {
this._$el.find('.eruda-open').rmClass('eruda-open')
}
_getSetting(id) {
let ret
@@ -197,89 +136,12 @@ export default class Settings extends Tool {
return ret
}
_bindEvent() {
const self = this
this._$el
.on('click', '.eruda-checkbox', function () {
const $input = $(this).find('input')
const id = $input.data('id')
const val = $input.get(0).checked
const setting = self._getSetting(id)
setting.config.set(setting.key, val)
})
.on('click', '.eruda-select .eruda-head', function () {
const $el = $(this).parent().find('ul')
const isOpen = $el.hasClass('eruda-open')
self._closeAll()
isOpen ? $el.rmClass('eruda-open') : $el.addClass('eruda-open')
})
.on('click', '.eruda-select li', function () {
const $this = $(this)
const $ul = $this.parent()
const val = $this.text()
const id = $ul.data('id')
const setting = self._getSetting(id)
$ul.rmClass('eruda-open')
$ul.parent().find('.eruda-head span').text(val)
setting.config.set(setting.key, val)
})
.on('click', '.eruda-range .eruda-head', function () {
const $el = $(this).parent().find('.eruda-input-container')
const isOpen = $el.hasClass('eruda-open')
self._closeAll()
isOpen ? $el.rmClass('eruda-open') : $el.addClass('eruda-open')
})
.on('change', '.eruda-range input', function () {
const $this = $(this)
const $container = $this.parent()
const id = $container.data('id')
const val = +$this.val()
const setting = self._getSetting(id)
setting.config.set(setting.key, val)
})
.on('input', '.eruda-range input', function () {
const $this = $(this)
const $container = $this.parent()
const id = $container.data('id')
const val = +$this.val()
const setting = self._getSetting(id)
const { min, max } = setting
$container.parent().find('.eruda-head span').text(val)
$container
.find('.eruda-range-track-progress')
.css('width', progress(val, min, max) + '%')
})
.on('click', '.eruda-color .eruda-head', function () {
const $el = $(this).parent().find('ul')
const isOpen = $el.hasClass('eruda-open')
self._closeAll()
isOpen ? $el.rmClass('eruda-open') : $el.addClass('eruda-open')
})
.on('click', '.eruda-color li', function () {
const $this = $(this)
const $ul = $this.parent()
const val = $this.css('background-color')
const id = $ul.data('id')
const setting = self._getSetting(id)
$ul.rmClass('eruda-open')
$ul.parent().find('.eruda-head span').css('background-color', val)
setting.config.set(setting.key, val)
})
this._setting.on('change', (id, val) => {
const setting = this._getSetting(id)
setting.config.set(setting.key, val)
})
}
static createCfg(name, data) {
return new LocalStore('eruda-' + name, data)
}
}
const progress = (val, min, max) =>
(((val - min) / (max - min)) * 100).toFixed(2)

View File

@@ -3,226 +3,4 @@
#settings {
@include overflow-auto(y);
.separator {
height: 10px;
}
.text {
padding: $padding;
color: var(--accent);
font-size: $font-size-s;
}
.select,
.range,
.color {
cursor: pointer;
}
.select .head,
.switch,
.range .head,
.color .head {
padding: $padding;
background: var(--darker-background);
font-size: $font-size;
border-bottom: 1px solid var(--border);
border-top: 1px solid var(--border);
color: var(--primary);
margin-top: -1px;
}
.select .head,
.range .head,
.color .head {
transition: background $anim-duration, color $anim-duration;
span {
float: right;
}
&:active {
background: var(--highlight);
color: var(--select-foreground);
}
}
.color .head span {
display: inline-block;
border: 1px solid var(--border);
width: 15px;
height: 15px;
}
.select ul {
display: none;
border-bottom: 1px solid var(--border);
color: var(--foreground);
&.open {
display: block;
}
li {
padding: $padding;
transition: background $anim-duration, color $anim-duration;
&:active {
background: var(--highlight);
color: var(--select-foreground);
}
}
}
.color ul {
display: none;
padding: $padding;
font-size: 0;
border-bottom: 1px solid var(--border);
&.open {
display: block;
}
li {
display: inline-block;
width: 20px;
border: 1px solid var(--border);
height: 20px;
margin-right: 10px;
}
}
.range .input-container {
display: none;
padding: $padding;
border-bottom: 1px solid var(--border);
position: relative;
&.open {
display: block;
}
.range-track {
height: 4px;
width: 100%;
padding: 0 $padding;
position: absolute;
left: 0;
top: 16px;
.range-track-bar {
background: var(--darker-background);
border-radius: 2px;
overflow: hidden;
width: 100%;
height: 4px;
.range-track-progress {
height: 100%;
background: var(--accent);
width: 50%;
}
}
}
input {
-webkit-appearance: none;
background: transparent;
height: 4px;
width: 100%;
position: relative;
top: -3px;
margin: 0 auto;
outline: none;
border-radius: 2px;
}
input::-webkit-slider-thumb {
-webkit-appearance: none;
position: relative;
top: 0px;
z-index: 1;
width: 16px;
border: none;
height: 16px;
border-radius: 10px;
border: 1px solid var(--border);
background: radial-gradient(
circle at center,
var(--dark) 0,
var(--dark) 15%,
var(--light) 22%,
var(--light) 100%
);
}
}
.switch {
.checkbox {
float: right;
position: relative;
vertical-align: top;
width: 46px;
height: 20px;
padding: 3px;
border-radius: 18px;
border: 1px solid var(--border);
cursor: pointer;
background-image: linear-gradient(
to bottom,
var(--dark),
var(--light) 25px
);
.input {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.label {
pointer-events: none;
position: relative;
display: block;
height: 12px;
font-size: 10px;
text-transform: uppercase;
background: var(--darker-background);
border-radius: inherit;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12),
inset 0 0 2px rgba(0, 0, 0, 0.15);
transition: 0.15s ease-out;
transition-property: opacity background;
&:before,
&:after {
position: absolute;
top: 50%;
margin-top: -0.5em;
line-height: 1;
transition: inherit;
}
}
.input:checked ~ .label {
background: var(--accent);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15),
inset 0 0 3px rgba(0, 0, 0, 0.2);
}
.input:checked ~ .label:before {
opacity: 0;
}
.input:checked ~ .label:after {
opacity: 1;
}
.handle {
position: absolute;
pointer-events: none;
top: 0;
left: 0;
width: 18px;
height: 18px;
border-radius: 10px;
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
background-image: linear-gradient(
to bottom,
var(--light) 40%,
var(--dark)
);
transition: left 0.15s ease-out;
}
.handle:before {
content: '';
position: absolute;
top: 50%;
left: 50%;
margin: -6px 0 0 -6px;
width: 12px;
height: 12px;
border-radius: 6px;
box-shadow: inset 0 1px rgba(0, 0, 0, 0.02);
background-image: linear-gradient(to bottom, var(--dark), var(--light));
}
.input:checked ~ .handle {
left: 30px;
box-shadow: -1px 1px 5px rgba(0, 0, 0, 0.2);
}
}
}
}

View File

@@ -2,15 +2,13 @@ import logger from '../lib/logger'
import emitter from '../lib/emitter'
import Url from 'licia/Url'
import now from 'licia/now'
import each from 'licia/each'
import isStr from 'licia/isStr'
import startWith from 'licia/startWith'
import $ from 'licia/$'
import upperFirst from 'licia/upperFirst'
import loadJs from 'licia/loadJs'
import trim from 'licia/trim'
import LunaModal from 'luna-modal'
import { safeStorage, isErudaEl } from '../lib/util'
import { isErudaEl } from '../lib/util'
import evalCss from '../lib/evalCss'
let style = null
@@ -158,23 +156,6 @@ export default [
},
desc: 'Visualize screen touches',
},
{
name: 'Restore Settings',
fn() {
const store = safeStorage('local')
const data = JSON.parse(JSON.stringify(store))
each(data, (val, key) => {
if (!isStr(val)) return
if (startWith(key, 'eruda')) store.removeItem(key)
})
window.location.reload()
},
desc: 'Restore defaults and reload',
},
]
evalCss(require('./searchText.scss'), document.head)

View File

@@ -233,6 +233,7 @@ export default {
require('luna-modal/luna-modal.css') +
require('luna-tab/luna-tab.css') +
require('luna-text-viewer/luna-text-viewer.css') +
require('luna-setting/luna-setting.css') +
require('./style/style.scss') +
require('./style/icon.css')
)

View File

@@ -356,3 +356,83 @@
background-color: var(--background);
}
}
.luna-setting {
color: var(--foreground);
background: var(--background);
}
.luna-setting-item {
&:hover {
background: var(--darker-background);
}
}
.luna-setting-item-title {
font-size: $font-size;
}
.luna-setting-item-separator {
border-color: var(--border);
}
.luna-setting-item-checkbox {
input {
border-color: var(--border);
&:checked {
background-color: var(--accent);
border-color: var(--accent);
}
}
}
.luna-setting-item-select {
.luna-setting-select {
select {
color: var(--foreground);
border-color: var(--border);
background: var(--background);
}
&:after {
border-top-color: var(--foreground);
}
}
}
.luna-setting-item-button {
button {
color: var(--accent);
background: var(--background);
border-color: var(--border);
&:hover,
&:active {
background: var(--darker-background);
}
&:active {
border: 1px solid var(--accent);
}
}
}
.luna-setting-item-number {
.luna-setting-range-container {
.luna-setting-range-track {
.luna-setting-range-track-bar {
background: var(--border);
.luna-setting-range-track-progress {
background: var(--accent);
}
}
}
input::-webkit-slider-thumb {
border-color: var(--border);
background: radial-gradient(
circle at center,
var(--dark) 0,
var(--dark) 15%,
var(--light) 22%,
var(--light) 100%
);
}
}
}