fix: copy/paste button error/done state class name switch
add: flex properties: flex-direction, justify-content, align-items, gap
fix: border witdh/color/style data error
This commit is contained in:
defaultkavy 2024-04-02 08:28:00 +08:00
parent 22d3148fce
commit e4a80e06ff
7 changed files with 52 additions and 42 deletions

1
.vscode/tasks.json vendored
View File

@ -25,7 +25,6 @@
{
"label": "dev-startup",
"dependsOn": [
"server",
"vite"
],
"problemMatcher": []

File diff suppressed because one or more lines are too long

View File

@ -29,7 +29,7 @@
<meta name="twitter:title" content="YouTube Chat Designer">
<meta name="twitter:description" content="YouTube Chat CSS design tool for streamer.">
<!-- <meta name="twitter:image" content=""> -->
<script type="module" crossorigin src="/assets/index-DTS3ifer.js"></script>
<script type="module" crossorigin src="/assets/index-CqaSrBDb.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-nOkcB8kh.css">
</head>
<body>

File diff suppressed because one or more lines are too long

View File

@ -22,7 +22,7 @@ export const $chat = new YouTubeChat().css({backgroundColor: '#131313'})
.send({name: 'リョウ', message: 'If you want to save your settings, using Copy JSON and save it, you can paste the JSON to recovery your settings.', role: 'Moderator'})
.send({name: '虹夏', message: 'Try to send message for test your design.', role: 'Owner'})
init();
modelInit();
const $app = $('app').content([
$('h1').content([
@ -78,9 +78,10 @@ const $app = $('app').content([
const json_string = await navigator.clipboard.readText();
try {
const json = JSON.parse(json_string);
init(json);
modelInit(json);
} catch (err) {
$button.content('Error!').class('error');
$button.content('Error!').class('error').removeClass('done');
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
$button.removeClass('error').content('Paste');
timer = undefined;
@ -88,7 +89,7 @@ const $app = $('app').content([
return;
}
load();
$button.content('Pasted!').class('done')
$button.content('Pasted!').class('done').removeClass('error')
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
$button.removeClass('done').content('Paste');
@ -177,15 +178,16 @@ $(document.body).content($app)
load();
window.addEventListener('resize', () => checkWindowSize())
function init(data = defaultStyle) {
function modelInit(data = defaultStyle) {
ROLE_MODEL_MAP.clear();
for (const role of ROLE_LIST) {
const STYLE_MAP = new Map<string, StyleModel>()
const STYLE_MAP = new Map<string, StyleModel>();
ROLE_MODEL_MAP.set(role, STYLE_MAP);
for (const element of ELEMENT_LIST) {
const model = new StyleModel(data[role][element]);
STYLE_MAP.set(element, model)
$chat.updateStyle(element, model, [role])
const initialized_data = dataInit(data[role][element]);
const model = new StyleModel(initialized_data);
STYLE_MAP.set(element, model);
$chat.updateStyle(element, model, [role]);
}
}
$view.deleteAllView().clear();
@ -200,7 +202,7 @@ function load() {
$view.switchView('Message');
$<$Input>('::.role-checkbox')?.forEach($input => $input.checked(false));
$<$Input>(':#normal')?.checked(true);
refreshPanel();
PANEL_MAP.forEach(panel => panel.update().layout())
}
function refreshPanel() {
@ -266,4 +268,11 @@ function checkWindowSize() {
} else {
if (!$app.inDOM()) $(document.body).content($app);
}
}
}
function dataInit(data: Partial<CSSStyleDeclaration>) {
switch (undefined) {
case data.gap: data.gap = '0px';
}
return data;
}

View File

@ -21,9 +21,9 @@ export class StyleModel {
}
const border = (dir: 'top' | 'right' | 'left' | 'bottom') => {
return {
[`border${firstCap(dir)}Style`]: filterMultitype(panel.$<$Select>(`#border-${dir}-style`)?.value(), this.data[`boder${firstCap(dir)}Style`]),
[`border${firstCap(dir)}Color`]: filterMultitype(panel.$<$Input>(`#border-${dir}-color`)?.value(), this.data[`boder${firstCap(dir)}Color`]),
[`border${firstCap(dir)}Width`]: filterMultitype(panel.$<$Input>(`#border-${dir}-width`)?.value(), this.data[`boder${firstCap(dir)}Color`], true)
[`border${firstCap(dir)}Style`]: filterMultitype(panel.$<$Select>(`#border-${dir}-style`)?.value(), this.data[`border${firstCap(dir)}Style`]),
[`border${firstCap(dir)}Color`]: filterMultitype(panel.$<$Input>(`#border-${dir}-color`)?.value(), this.data[`border${firstCap(dir)}Color`]),
[`border${firstCap(dir)}Width`]: filterMultitype(panel.$<$Input>(`#border-${dir}-width`)?.value(), this.data[`border${firstCap(dir)}Width`], true)
}
}
@ -62,29 +62,12 @@ export class StyleModel {
display: filterMultitype(panel.$<$Select>('#display')?.value(), this.data.display),
height: filterMultitype(panel.$<$Input>('#height')?.value(), this.data.height, true),
width: filterMultitype(panel.$<$Input>('#width')?.value(), this.data.width, true),
flexDirection: filterMultitype(panel.$<$Input>('#flex-direction')?.value(), this.data.flexDirection),
justifyContent: filterMultitype(panel.$<$Input>('#justify-content')?.value(), this.data.justifyContent),
alignItems: filterMultitype(panel.$<$Input>('#align-items')?.value(), this.data.alignItems),
gap: filterMultitype(panel.$<$Input>('#gap')?.value(), this.data.gap, true),
}
this.data = data;
return this;
}
cssObject() {
const json = {};
const convert = (passKey: string | null, data: Object) => {
for (let [key, value] of Object.entries(data)) {
key = passKey ? passKey + key.charAt(0).toUpperCase() + key.slice(1) : key;
if (value instanceof Object === false) {
if (typeof value === 'number' && key !== 'opacity') value = `${value}px`;
Object.assign(json, {[`${key}`]: value});
continue;
}
convert(key, value);
}
}
convert(null, this.data);
return json
}
css() {
}
}

View File

@ -1,4 +1,4 @@
import { $Container } from "fluentx";
import { $Container, $State } from "fluentx";
import { ColorInput } from "../component/ColorInput";
import { RangeInput } from "../component/RangeInput";
import { SelectInput } from "../component/SelectInput";
@ -10,6 +10,7 @@ import { firstCap, propCap } from "./util";
export class StylePanel extends $Container {
type: StyleType;
name: string;
flex_hidden$ = $.state(false);
constructor(name: string, type: StyleType) {
super('div');
this.staticClass('style-panel');
@ -26,6 +27,7 @@ export class StylePanel extends $Container {
model.update(this)
$chat.updateStyle(this.name, model, [role]);
});
this.flex_hidden$.set(this.data?.display !== 'flex');
return this;
}
@ -44,6 +46,22 @@ export class StylePanel extends $Container {
])
]),
$('section').content([
$('h3').content('Flex'),
$('div').content([
new SelectInput('flex-direction').label('Direction').add([
['row', 'column', 'row-reverse', 'column-reverse',].map(value => $('option').content(value).value(value))
]).value(this.data.flexDirection),
new RangeInput('gap').value(this.data.gap).unit('px').min(0).max(100).label('Gap'),
new SelectInput('justify-content').label('Justify Content').add([
['start', 'center', 'end', 'stretch', 'space-around', 'space-evenly', 'space-between'].map(value => $('option').content(value).value(value))
]).value(this.data.justifyContent),
new SelectInput('align-items').label('Align Items').add([
['start', 'center', 'end', 'stretch', 'space-around', 'space-evenly', 'space-between'].map(value => $('option').content(value).value(value))
]).value(this.data.alignItems)
])
]).hide(this.flex_hidden$),
this.type === 'text' ? $('section').content([
$('h3').content('Font'),
$('div').content([