add: Timestamp element
add: Float property
fix: word-wrap: break-word on message and author-name element
update: hide paid message on export css
This commit is contained in:
defaultkavy 2024-04-02 09:57:54 +08:00
parent 27996c05ed
commit 988a9be4c2
12 changed files with 102 additions and 80 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -29,8 +29,8 @@
<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-BKk9KBzt.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-nOkcB8kh.css">
<script type="module" crossorigin src="/assets/index-BpVNZrte.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DWvRl_zt.css">
</head>
<body>
</body>

View File

@ -1,5 +1,5 @@
export const config = {
version: 'v1.0.6',
version: 'v1.0.7',
github_homepage: 'https://github.com/defaultkavy/youtube-chat-designer',
author_link: 'https://x.com/defaultkavy'
}

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,8 @@ yt-live-chat-renderer #panel-pages,
yt-live-chat-renderer #promo,
yt-live-chat-viewer-engagement-message-renderer,
yt-live-chat-banner-manager,
yt-live-chat-docked-message {
yt-live-chat-docked-message,
yt-live-chat-paid-message-renderer {
display: none !important;
}
#item-scroller {
@ -17,6 +18,9 @@ yt-live-chat-docked-message {
html, body, yt-live-chat-app, yt-live-chat-renderer {
background: #00000000 !important;
}
yt-live-chat-text-message-renderer #message, yt-live-chat-text-message-renderer #author-name {
word-wrap: break-word;
}
yt-live-chat-text-message-renderer {
position: relative;
overflow: hidden;

View File

@ -399,6 +399,7 @@ yt-live-chat-text-message-renderer {
#prepend-chat-badges {}
#author-name {
word-wrap: break-word;
#chip-badges {}
}
@ -422,6 +423,7 @@ yt-live-chat-text-message-renderer {
}
#message {
word-wrap: break-word;
}
#deleted-state {}

View File

@ -1,7 +1,7 @@
import { $, $Button, $Select, $Textarea } from 'fluentx';
import { StylePanel } from './structure/StylePanel';
import { StyleModel } from './structure/StyleModel';
import { defaultStyle } from './data/defaultStyle';
import { defaultStyle, init_element_style } from './data/defaultStyle';
import { YouTubeChat } from './structure/YouTubeChat';
import { $Input } from 'fluentx/lib/$Input';
import { ColorInput } from './component/ColorInput';
@ -10,8 +10,8 @@ import { config } from './config';
export const ROLE_MODEL_MAP = new Map<string, Map<string, StyleModel>>();
const ROLE_LIST = ['Normal', 'Member', 'Moderator', 'Owner'];
const ELEMENT_LIST = ['Message', 'Name', 'Avatar', 'Author Area', 'Content Area', 'Outer Area'];
const IS_TEXT_ELEMENT = ['Message', 'Name', 'Timestamp'];
const ELEMENT_LIST = ['Message', 'Name', 'Avatar', 'Time', 'Author Area', 'Content Area', 'Outer Area'];
const IS_TEXT_ELEMENT = ['Message', 'Name', 'Time'];
const IS_IMAGE_ELEMENT = ['Badge', 'Avatar'];
const PANEL_MAP = new Map<string, StylePanel>();
@ -185,7 +185,7 @@ function modelInit(data = defaultStyle) {
const STYLE_MAP = new Map<string, StyleModel>();
ROLE_MODEL_MAP.set(role, STYLE_MAP);
for (const element of ELEMENT_LIST) {
const initialized_data = dataInit(data[role][element]);
const initialized_data = dataInit(data[role][element] ?? defaultStyle[role][element] ?? init_element_style);
const model = new StyleModel(initialized_data);
STYLE_MAP.set(element, model);
$chat.updateStyle(element, model, [role]);
@ -233,6 +233,7 @@ function exportCSS() {
case 'Avatar': selector += ' #author-photo'; break;
case 'Author Area': selector += ' yt-live-chat-author-clip'; break;
case 'Content Area': selector += ' #content'; break;
case 'Time': selector += ' #timestamp'; break;
case 'Outer Area': break;
}
let stylesheet = '';
@ -274,6 +275,7 @@ function checkWindowSize() {
function dataInit(data: Partial<CSSStyleDeclaration>) {
switch (undefined) {
case data.gap: data.gap = '0px';
case data.float: data.float = 'none';
}
return data;
}

View File

@ -66,6 +66,7 @@ export class StyleModel {
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),
float: filterMultitype(panel.$<$Input>('#float')?.value(), this.data.float),
}
this.data = data;
return this;

View File

@ -40,9 +40,12 @@ export class StylePanel extends $Container {
$('h3').content('Properties'),
$('div').content([
new SelectInput('display').label('Display').add([
['block', 'inline', 'flex', 'none'].map(value => $('option').content(value).value(value))
['block', 'inline', 'flex', 'inline-flex', 'none'].map(value => $('option').content(value).value(value))
]).value(this.data.display),
new RangeInput('opacity').value(this.data.opacity).unit('px').min(0).max(1).label('Opacity').self($input => {$input.$range.step(0.01); $input.$value.step(0.1)}),
new SelectInput('float').label('Float').add([
['left', 'right', 'none'].map(value => $('option').content(value).value(value))
]).value(this.data.float),
])
]),

View File

@ -39,7 +39,7 @@ export class YouTubeMessage extends $Container {
$('img').src(`/${this.avatar_url}`)
]),
this.$content.content([
this.$timestamp,
this.$timestamp.content(new Intl.DateTimeFormat('en', {timeStyle: 'short'}).format(new Date())),
this.$author_area.content([
this.$name.content(this.data.name),
$('span').id('chat-badges').content([
@ -72,6 +72,7 @@ export class YouTubeMessage extends $Container {
case 'Content Area': this.$content.css(model.data); break;
case 'Author Area': this.$author_area.css(model.data); break;
case 'Outer Area': this.css(model.data); break;
case 'Time': this.$timestamp.css(model.data); break;
}
}
@ -80,6 +81,7 @@ export class YouTubeMessage extends $Container {
case 'Message': this.hintPosition(this.$message); break;
case 'Name': this.hintPosition(this.$name); break;
case 'Avatar': this.hintPosition(this.$avatar); break;
case 'Time': this.hintPosition(this.$timestamp); break;
case 'Content Area': this.hintPosition(this.$content); break;
case 'Author Area': this.hintPosition(this.$author_area); break;
case 'Outer Area': this.hintPosition(this); break;