mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-11 10:31:47 +00:00
proper support for tree-shakeable Lit components
This commit is contained in:
@ -6,6 +6,7 @@ import { IconChevronRight } from '@mdui/icons/chevron-right.js';
|
|||||||
import { createPlugin } from '@/utils';
|
import { createPlugin } from '@/utils';
|
||||||
|
|
||||||
import { t } from '@/i18n';
|
import { t } from '@/i18n';
|
||||||
|
import { LitElementWrapper } from '@/solit';
|
||||||
|
|
||||||
export default createPlugin({
|
export default createPlugin({
|
||||||
name: () => t('plugins.navigation.name'),
|
name: () => t('plugins.navigation.name'),
|
||||||
@ -17,9 +18,6 @@ export default createPlugin({
|
|||||||
renderer: {
|
renderer: {
|
||||||
buttonContainer: document.createElement('div'),
|
buttonContainer: document.createElement('div'),
|
||||||
start() {
|
start() {
|
||||||
const doNotTreeShake = [IconChevronLeft, IconChevronRight];
|
|
||||||
((a) => {})(doNotTreeShake);
|
|
||||||
|
|
||||||
if (!this.buttonContainer) {
|
if (!this.buttonContainer) {
|
||||||
this.buttonContainer = document.createElement('div');
|
this.buttonContainer = document.createElement('div');
|
||||||
}
|
}
|
||||||
@ -31,8 +29,9 @@ export default createPlugin({
|
|||||||
content={t('plugins.navigation.templates.back.title')}
|
content={t('plugins.navigation.templates.back.title')}
|
||||||
>
|
>
|
||||||
<mdui-button-icon onClick={() => history.back()}>
|
<mdui-button-icon onClick={() => history.back()}>
|
||||||
<mdui-icon-chevron-left
|
<LitElementWrapper
|
||||||
style={{ padding: '5px', scale: '1.5' }}
|
elementClass={IconChevronLeft}
|
||||||
|
props={{ style: { padding: '5px', scale: '1.5' } }}
|
||||||
/>
|
/>
|
||||||
</mdui-button-icon>
|
</mdui-button-icon>
|
||||||
</mdui-tooltip>
|
</mdui-tooltip>
|
||||||
@ -40,8 +39,9 @@ export default createPlugin({
|
|||||||
content={t('plugins.navigation.templates.forward.title')}
|
content={t('plugins.navigation.templates.forward.title')}
|
||||||
>
|
>
|
||||||
<mdui-button-icon onClick={() => history.forward()}>
|
<mdui-button-icon onClick={() => history.forward()}>
|
||||||
<mdui-icon-chevron-right
|
<LitElementWrapper
|
||||||
style={{ padding: '5px', scale: '1.5' }}
|
elementClass={IconChevronRight}
|
||||||
|
props={{ style: { padding: '5px', scale: '1.5' } }}
|
||||||
/>
|
/>
|
||||||
</mdui-button-icon>
|
</mdui-button-icon>
|
||||||
</mdui-tooltip>
|
</mdui-tooltip>
|
||||||
|
|||||||
@ -23,6 +23,8 @@ import { IconError } from '@mdui/icons/error.js';
|
|||||||
import { IconStar } from '@mdui/icons/star.js';
|
import { IconStar } from '@mdui/icons/star.js';
|
||||||
import { IconStarBorder } from '@mdui/icons/star-border.js';
|
import { IconStarBorder } from '@mdui/icons/star-border.js';
|
||||||
|
|
||||||
|
import { LitElementWrapper } from '@/solit';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type ProviderName,
|
type ProviderName,
|
||||||
ProviderNames,
|
ProviderNames,
|
||||||
@ -58,7 +60,9 @@ const providerBias = (p: ProviderName) =>
|
|||||||
(lyricsStore.lyrics[p].state === 'done' ? 1 : -1) +
|
(lyricsStore.lyrics[p].state === 'done' ? 1 : -1) +
|
||||||
(lyricsStore.lyrics[p].data?.lines?.length ? 2 : -1) +
|
(lyricsStore.lyrics[p].data?.lines?.length ? 2 : -1) +
|
||||||
// eslint-disable-next-line prettier/prettier
|
// eslint-disable-next-line prettier/prettier
|
||||||
(lyricsStore.lyrics[p].data?.lines?.length && p === ProviderNames.YTMusic ? 1 : 0) +
|
(lyricsStore.lyrics[p].data?.lines?.length && p === ProviderNames.YTMusic
|
||||||
|
? 1
|
||||||
|
: 0) +
|
||||||
(lyricsStore.lyrics[p].data?.lyrics ? 1 : -1);
|
(lyricsStore.lyrics[p].data?.lyrics ? 1 : -1);
|
||||||
|
|
||||||
const pickBestProvider = () => {
|
const pickBestProvider = () => {
|
||||||
@ -82,17 +86,6 @@ const [hasManuallySwitchedProvider, setHasManuallySwitchedProvider] =
|
|||||||
export const LyricsPicker = (props: {
|
export const LyricsPicker = (props: {
|
||||||
setStickRef: Setter<HTMLElement | null>;
|
setStickRef: Setter<HTMLElement | null>;
|
||||||
}) => {
|
}) => {
|
||||||
const doNotTreeShake = [
|
|
||||||
IconChevronLeft,
|
|
||||||
IconChevronRight,
|
|
||||||
IconCheckCircle,
|
|
||||||
IconWarning,
|
|
||||||
IconError,
|
|
||||||
IconStar,
|
|
||||||
IconStarBorder,
|
|
||||||
];
|
|
||||||
((a) => {})(doNotTreeShake);
|
|
||||||
|
|
||||||
const [videoId, setVideoId] = createSignal<string | null>(null);
|
const [videoId, setVideoId] = createSignal<string | null>(null);
|
||||||
const [starredProvider, setStarredProvider] =
|
const [starredProvider, setStarredProvider] =
|
||||||
createSignal<ProviderName | null>(null);
|
createSignal<ProviderName | null>(null);
|
||||||
@ -200,10 +193,13 @@ export const LyricsPicker = (props: {
|
|||||||
<div class="lyrics-picker" ref={props.setStickRef}>
|
<div class="lyrics-picker" ref={props.setStickRef}>
|
||||||
<div class="lyrics-picker-left">
|
<div class="lyrics-picker-left">
|
||||||
<mdui-button-icon>
|
<mdui-button-icon>
|
||||||
<mdui-icon-chevron-left
|
<LitElementWrapper
|
||||||
onClick={previous}
|
elementClass={IconChevronLeft}
|
||||||
role="button"
|
props={{
|
||||||
style={{ padding: '5px' }}
|
onClick: previous,
|
||||||
|
role: 'button',
|
||||||
|
style: { padding: '5px' },
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</mdui-button-icon>
|
</mdui-button-icon>
|
||||||
</div>
|
</div>
|
||||||
@ -234,9 +230,9 @@ export const LyricsPicker = (props: {
|
|||||||
/>
|
/>
|
||||||
</Match>
|
</Match>
|
||||||
<Match when={currentLyrics().state === 'error'}>
|
<Match when={currentLyrics().state === 'error'}>
|
||||||
<mdui-icon-error
|
<LitElementWrapper
|
||||||
style={{ padding: '5px', scale: '0.8' }}
|
elementClass={IconError}
|
||||||
tabindex="-1"
|
props={{ style: { padding: '5px', scale: '0.8' } }}
|
||||||
/>
|
/>
|
||||||
</Match>
|
</Match>
|
||||||
<Match
|
<Match
|
||||||
@ -246,9 +242,9 @@ export const LyricsPicker = (props: {
|
|||||||
currentLyrics().data?.lyrics)
|
currentLyrics().data?.lyrics)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<mdui-icon-check-circle
|
<LitElementWrapper
|
||||||
style={{ padding: '5px', scale: '0.8' }}
|
elementClass={IconCheckCircle}
|
||||||
tabindex="-1"
|
props={{ style: { padding: '5px', scale: '0.8' } }}
|
||||||
/>
|
/>
|
||||||
</Match>
|
</Match>
|
||||||
<Match
|
<Match
|
||||||
@ -258,9 +254,9 @@ export const LyricsPicker = (props: {
|
|||||||
!currentLyrics().data?.lyrics
|
!currentLyrics().data?.lyrics
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<mdui-icon-warning
|
<LitElementWrapper
|
||||||
style={{ padding: '5px', scale: '0.8' }}
|
elementClass={IconWarning}
|
||||||
tabindex="-1"
|
props={{ style: { padding: '5px', scale: '0.8' } }}
|
||||||
/>
|
/>
|
||||||
</Match>
|
</Match>
|
||||||
</Switch>
|
</Switch>
|
||||||
@ -270,10 +266,12 @@ export const LyricsPicker = (props: {
|
|||||||
/>
|
/>
|
||||||
<mdui-button-icon onClick={toggleStar} tabindex={-1}>
|
<mdui-button-icon onClick={toggleStar} tabindex={-1}>
|
||||||
<Show
|
<Show
|
||||||
fallback={<mdui-icon-star-border />}
|
fallback={
|
||||||
|
<LitElementWrapper elementClass={IconStarBorder} />
|
||||||
|
}
|
||||||
when={starredProvider() === provider()}
|
when={starredProvider() === provider()}
|
||||||
>
|
>
|
||||||
<mdui-icon-star />
|
<LitElementWrapper elementClass={IconStar} />
|
||||||
</Show>
|
</Show>
|
||||||
</mdui-button-icon>
|
</mdui-button-icon>
|
||||||
</div>
|
</div>
|
||||||
@ -298,10 +296,13 @@ export const LyricsPicker = (props: {
|
|||||||
|
|
||||||
<div class="lyrics-picker-left">
|
<div class="lyrics-picker-left">
|
||||||
<mdui-button-icon>
|
<mdui-button-icon>
|
||||||
<mdui-icon-chevron-right
|
<LitElementWrapper
|
||||||
onClick={next}
|
elementClass={IconChevronRight}
|
||||||
role="button"
|
props={{
|
||||||
style={{ padding: '5px' }}
|
onClick: next,
|
||||||
|
role: 'button',
|
||||||
|
style: { padding: '5px' },
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</mdui-button-icon>
|
</mdui-button-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
26
src/solit.tsx
Normal file
26
src/solit.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// A SolidJS wrapper for a LitElement
|
||||||
|
|
||||||
|
import { createSignal, onMount, Show } from 'solid-js';
|
||||||
|
import { Dynamic } from 'solid-js/web';
|
||||||
|
|
||||||
|
export interface LitElementWrapperProps {
|
||||||
|
elementClass: CustomElementConstructor;
|
||||||
|
props?: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LitElementWrapper = (props: LitElementWrapperProps) => {
|
||||||
|
const [tagName, setTagName] = createSignal<string | null>(null);
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
// Create instance to discover tag name
|
||||||
|
const el = new props.elementClass();
|
||||||
|
setTagName(el.tagName.toLowerCase());
|
||||||
|
el.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Show when={tagName()}>
|
||||||
|
<Dynamic component={tagName()!} {...(props.props || {})} />
|
||||||
|
</Show>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user