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:title" content="YouTube Chat Designer">
<meta name="twitter:description" content="YouTube Chat CSS design tool for streamer."> <meta name="twitter:description" content="YouTube Chat CSS design tool for streamer.">
<!-- <meta name="twitter:image" content=""> --> <!-- <meta name="twitter:image" content=""> -->
<script type="module" crossorigin src="/assets/index-BKk9KBzt.js"></script> <script type="module" crossorigin src="/assets/index-BpVNZrte.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-nOkcB8kh.css"> <link rel="stylesheet" crossorigin href="/assets/index-DWvRl_zt.css">
</head> </head>
<body> <body>
</body> </body>

View File

@ -1,5 +1,5 @@
export const config = { export const config = {
version: 'v1.0.6', version: 'v1.0.7',
github_homepage: 'https://github.com/defaultkavy/youtube-chat-designer', github_homepage: 'https://github.com/defaultkavy/youtube-chat-designer',
author_link: 'https://x.com/defaultkavy' 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-renderer #promo,
yt-live-chat-viewer-engagement-message-renderer, yt-live-chat-viewer-engagement-message-renderer,
yt-live-chat-banner-manager, yt-live-chat-banner-manager,
yt-live-chat-docked-message { yt-live-chat-docked-message,
yt-live-chat-paid-message-renderer {
display: none !important; display: none !important;
} }
#item-scroller { #item-scroller {
@ -17,6 +18,9 @@ yt-live-chat-docked-message {
html, body, yt-live-chat-app, yt-live-chat-renderer { html, body, yt-live-chat-app, yt-live-chat-renderer {
background: #00000000 !important; 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 { yt-live-chat-text-message-renderer {
position: relative; position: relative;
overflow: hidden; overflow: hidden;

View File

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

View File

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

View File

@ -66,6 +66,7 @@ export class StyleModel {
justifyContent: filterMultitype(panel.$<$Input>('#justify-content')?.value(), this.data.justifyContent), justifyContent: filterMultitype(panel.$<$Input>('#justify-content')?.value(), this.data.justifyContent),
alignItems: filterMultitype(panel.$<$Input>('#align-items')?.value(), this.data.alignItems), alignItems: filterMultitype(panel.$<$Input>('#align-items')?.value(), this.data.alignItems),
gap: filterMultitype(panel.$<$Input>('#gap')?.value(), this.data.gap, true), gap: filterMultitype(panel.$<$Input>('#gap')?.value(), this.data.gap, true),
float: filterMultitype(panel.$<$Input>('#float')?.value(), this.data.float),
} }
this.data = data; this.data = data;
return this; return this;

View File

@ -40,9 +40,12 @@ export class StylePanel extends $Container {
$('h3').content('Properties'), $('h3').content('Properties'),
$('div').content([ $('div').content([
new SelectInput('display').label('Display').add([ 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), ]).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 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}`) $('img').src(`/${this.avatar_url}`)
]), ]),
this.$content.content([ this.$content.content([
this.$timestamp, this.$timestamp.content(new Intl.DateTimeFormat('en', {timeStyle: 'short'}).format(new Date())),
this.$author_area.content([ this.$author_area.content([
this.$name.content(this.data.name), this.$name.content(this.data.name),
$('span').id('chat-badges').content([ $('span').id('chat-badges').content([
@ -72,6 +72,7 @@ export class YouTubeMessage extends $Container {
case 'Content Area': this.$content.css(model.data); break; case 'Content Area': this.$content.css(model.data); break;
case 'Author Area': this.$author_area.css(model.data); break; case 'Author Area': this.$author_area.css(model.data); break;
case 'Outer Area': this.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 'Message': this.hintPosition(this.$message); break;
case 'Name': this.hintPosition(this.$name); break; case 'Name': this.hintPosition(this.$name); break;
case 'Avatar': this.hintPosition(this.$avatar); break; case 'Avatar': this.hintPosition(this.$avatar); break;
case 'Time': this.hintPosition(this.$timestamp); break;
case 'Content Area': this.hintPosition(this.$content); break; case 'Content Area': this.hintPosition(this.$content); break;
case 'Author Area': this.hintPosition(this.$author_area); break; case 'Author Area': this.hintPosition(this.$author_area); break;
case 'Outer Area': this.hintPosition(this); break; case 'Outer Area': this.hintPosition(this); break;