style: add eslint and prettier, fix style errors
This commit is contained in:
@@ -1,37 +1,37 @@
|
||||
<script lang="ts">
|
||||
import { PANEL_SETTINGS } from "$lib/constants";
|
||||
import { imageConfigState } from "$states/imageConfig.svelte";
|
||||
import { textConfigState } from "$states/textConfig.svelte";
|
||||
import { Image, Layer, Stage, Text } from "svelte-konva";
|
||||
|
||||
interface Props {
|
||||
text: string;
|
||||
stage: Stage | undefined;
|
||||
}
|
||||
|
||||
let { text, stage = $bindable() }: Props = $props();
|
||||
|
||||
let x = $derived(textConfigState.paddingX);
|
||||
let y = $derived(10 + textConfigState.offsetY);
|
||||
let width = $derived(PANEL_SETTINGS.PANEL_WIDTH - 2 * textConfigState.paddingX);
|
||||
let height = PANEL_SETTINGS.PANEL_HEIGHT_DEFAULT;
|
||||
</script>
|
||||
|
||||
<Stage width={320} height={100} bind:this={stage}>
|
||||
<Layer>
|
||||
<Image image={imageConfigState.image}></Image>
|
||||
<Text
|
||||
{text}
|
||||
{x}
|
||||
{y}
|
||||
{width}
|
||||
{height}
|
||||
fontSize={textConfigState.fontSize}
|
||||
fill={textConfigState.color}
|
||||
fontFamily={textConfigState.fontFamily}
|
||||
align={textConfigState.align}
|
||||
wrap="none"
|
||||
ellipsis={true}
|
||||
/>
|
||||
</Layer>
|
||||
</Stage>
|
||||
<script lang="ts">
|
||||
import { PANEL_SETTINGS } from "$lib/constants";
|
||||
import { imageConfigState } from "$states/imageConfig.svelte";
|
||||
import { textConfigState } from "$states/textConfig.svelte";
|
||||
import { Image, Layer, Stage, Text } from "svelte-konva";
|
||||
|
||||
interface Props {
|
||||
text: string;
|
||||
stage: Stage | undefined;
|
||||
}
|
||||
|
||||
let { text, stage = $bindable() }: Props = $props();
|
||||
|
||||
let x = $derived(textConfigState.paddingX);
|
||||
let y = $derived(10 + textConfigState.offsetY);
|
||||
let width = $derived(PANEL_SETTINGS.PANEL_WIDTH - 2 * textConfigState.paddingX);
|
||||
let height = PANEL_SETTINGS.PANEL_HEIGHT_DEFAULT;
|
||||
</script>
|
||||
|
||||
<Stage width={320} height={100} bind:this={stage}>
|
||||
<Layer>
|
||||
<Image image={imageConfigState.image}></Image>
|
||||
<Text
|
||||
{text}
|
||||
{x}
|
||||
{y}
|
||||
{width}
|
||||
{height}
|
||||
fontSize={textConfigState.fontSize}
|
||||
fill={textConfigState.color}
|
||||
fontFamily={textConfigState.fontFamily}
|
||||
align={textConfigState.align}
|
||||
wrap="none"
|
||||
ellipsis={true}
|
||||
/>
|
||||
</Layer>
|
||||
</Stage>
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { konvaAllStagesState } from "$states/konvaAllStages.svelte";
|
||||
import { textsState } from "$states/texts.svelte";
|
||||
|
||||
import Preview from "./Preview.svelte";
|
||||
</script>
|
||||
|
||||
<div class="outside-display">
|
||||
{#each textsState.texts as { text, id }, idx (id)}
|
||||
<Preview {text} bind:stage={konvaAllStagesState[idx]} />
|
||||
{:else}
|
||||
<p>No texts to preview</p>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.outside-display {
|
||||
position: fixed;
|
||||
top: -1000px;
|
||||
left: -1000px;
|
||||
}
|
||||
</style>
|
||||
<script lang="ts">
|
||||
import { konvaAllStagesState } from "$states/konvaAllStages.svelte";
|
||||
import { textsState } from "$states/texts.svelte";
|
||||
|
||||
import Preview from "./Preview.svelte";
|
||||
</script>
|
||||
|
||||
<div class="outside-display">
|
||||
{#each textsState.texts as { text, id }, idx (id)}
|
||||
<Preview {text} bind:stage={konvaAllStagesState[idx]} />
|
||||
{:else}
|
||||
<p>No texts to preview</p>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.outside-display {
|
||||
position: fixed;
|
||||
top: -1000px;
|
||||
left: -1000px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,40 +1,46 @@
|
||||
<script lang="ts">
|
||||
import Button from "$components/ui/Button.svelte";
|
||||
import { SlideDirection, type SlideDirectionType } from "$lib/constants";
|
||||
import ChevronLeft from "~icons/lucide/chevron-left";
|
||||
import ChevronRight from "~icons/lucide/chevron-right";
|
||||
|
||||
interface Props {
|
||||
current: number;
|
||||
direction: SlideDirectionType;
|
||||
max: number;
|
||||
}
|
||||
|
||||
let { current = $bindable(), direction = $bindable(SlideDirection.NEXT), max }: Props = $props();
|
||||
|
||||
let isFirst = $derived(current === 0);
|
||||
let isLast = $derived(current === max - 1);
|
||||
|
||||
function prev() {
|
||||
if (current > 0) current--;
|
||||
direction = SlideDirection.PREV;
|
||||
}
|
||||
|
||||
async function next() {
|
||||
if (current < max - 1) current++;
|
||||
direction = SlideDirection.NEXT;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Button icon={ChevronLeft} ariaLabel="Previous slide" type="mini" onclick={prev} disabled={isFirst} />
|
||||
<span class="panel-indicator">{current + 1} / {max}</span>
|
||||
<Button icon={ChevronRight} ariaLabel="Next slide" type="mini" onclick={next} disabled={isLast} />
|
||||
|
||||
<style>
|
||||
.panel-indicator {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
min-width: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<script lang="ts">
|
||||
import Button from "$components/ui/Button.svelte";
|
||||
import { SlideDirection, type SlideDirectionType } from "$lib/constants";
|
||||
import ChevronLeft from "~icons/lucide/chevron-left";
|
||||
import ChevronRight from "~icons/lucide/chevron-right";
|
||||
|
||||
interface Props {
|
||||
current: number;
|
||||
direction: SlideDirectionType;
|
||||
max: number;
|
||||
}
|
||||
|
||||
let { current = $bindable(), direction = $bindable(SlideDirection.NEXT), max }: Props = $props();
|
||||
|
||||
let isFirst = $derived(current === 0);
|
||||
let isLast = $derived(current === max - 1);
|
||||
|
||||
function prev() {
|
||||
if (current > 0) current--;
|
||||
direction = SlideDirection.PREV;
|
||||
}
|
||||
|
||||
async function next() {
|
||||
if (current < max - 1) current++;
|
||||
direction = SlideDirection.NEXT;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Button
|
||||
icon={ChevronLeft}
|
||||
ariaLabel="Previous slide"
|
||||
type="mini"
|
||||
onclick={prev}
|
||||
disabled={isFirst}
|
||||
/>
|
||||
<span class="panel-indicator">{current + 1} / {max}</span>
|
||||
<Button icon={ChevronRight} ariaLabel="Next slide" type="mini" onclick={next} disabled={isLast} />
|
||||
|
||||
<style>
|
||||
.panel-indicator {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
min-width: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,136 +1,144 @@
|
||||
<script lang="ts">
|
||||
import Card from "$components/layout/Card.svelte";
|
||||
import Badge from "$components/ui/Badge.svelte";
|
||||
import Button from "$components/ui/Button.svelte";
|
||||
import { PANEL_SETTINGS, TRANSITION_DURATION, type SlideDirectionType } from "$lib/constants";
|
||||
import { downloadService, type DownloadItem } from "$services/downloadService";
|
||||
import { konvaAllStagesState } from "$states/konvaAllStages.svelte";
|
||||
import { konvaStageState } from "$states/konvaStage.svelte";
|
||||
import { textsState } from "$states/texts.svelte";
|
||||
import { fly } from "svelte/transition";
|
||||
import Download from "~icons/lucide/download";
|
||||
import StickyNote from "~icons/lucide/sticky-note";
|
||||
import Preview from "./Preview.svelte";
|
||||
import PreviewAll from "./PreviewAll.svelte";
|
||||
import PreviewControls from "./PreviewControls.svelte";
|
||||
|
||||
let current: number = $state(0);
|
||||
let direction: SlideDirectionType = $state("next");
|
||||
|
||||
let xDirection = $derived(direction == "next" ? PANEL_SETTINGS.PANEL_WIDTH : -PANEL_SETTINGS.PANEL_WIDTH);
|
||||
|
||||
$effect(() => {
|
||||
if (textsState.texts.length === 0) {
|
||||
current = 0;
|
||||
} else {
|
||||
if (current > textsState.texts.length - 1) {
|
||||
current = textsState.texts.length - 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function downloadAll() {
|
||||
let downloadItems: Array<DownloadItem> = textsState.texts.map((text, idx) => ({
|
||||
filename: text.text,
|
||||
stage: konvaAllStagesState[idx]?.node,
|
||||
}));
|
||||
|
||||
downloadService.downloadAll(downloadItems);
|
||||
}
|
||||
|
||||
function downloadCurrent() {
|
||||
let node = konvaStageState.stage?.node;
|
||||
if (node) {
|
||||
downloadService.downloadPanel(node, textsState.texts[current].text);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#snippet panelTitle()}
|
||||
Панели <Badge text={textsState.texts.length} />
|
||||
{/snippet}
|
||||
|
||||
{#snippet panelControls()}
|
||||
<PreviewControls bind:current bind:direction max={textsState.texts.length} />
|
||||
{/snippet}
|
||||
|
||||
<Card title={panelTitle} titleSnippet={panelControls}>
|
||||
<div class="panel-viewer">
|
||||
<div class="panel-display">
|
||||
{#if textsState.texts.length}
|
||||
{#key current}
|
||||
{@const text = textsState?.texts[current]?.text}
|
||||
<div
|
||||
class="konva-wrapper"
|
||||
in:fly={{ x: xDirection, duration: TRANSITION_DURATION }}
|
||||
out:fly={{ x: -xDirection, duration: TRANSITION_DURATION }}
|
||||
>
|
||||
<Preview {text} bind:stage={konvaStageState.stage} />
|
||||
</div>
|
||||
{/key}
|
||||
{:else}
|
||||
<div class="empty-state" aria-label="Empty texts info">
|
||||
<StickyNote />
|
||||
<p>Добавьте тексты для создания панелей</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="panel-actions">
|
||||
<Button label="Скачать всё" ariaLabel="Download all" icon={Download} onclick={downloadAll} />
|
||||
<Button label="Скачать" ariaLabel="Download current" type="secondary" icon={Download} onclick={downloadCurrent} />
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<PreviewAll />
|
||||
|
||||
<style>
|
||||
.panel-viewer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.panel-display {
|
||||
background: var(--surface-subtle);
|
||||
border-radius: var(--radius);
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 150px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.panel-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 32px 16px;
|
||||
}
|
||||
|
||||
.empty-state :global(svg) {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin: 0 auto 12px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.konva-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
<script lang="ts">
|
||||
import Card from "$components/layout/Card.svelte";
|
||||
import Badge from "$components/ui/Badge.svelte";
|
||||
import Button from "$components/ui/Button.svelte";
|
||||
import { PANEL_SETTINGS, TRANSITION_DURATION, type SlideDirectionType } from "$lib/constants";
|
||||
import { downloadService, type DownloadItem } from "$services/downloadService";
|
||||
import { konvaAllStagesState } from "$states/konvaAllStages.svelte";
|
||||
import { konvaStageState } from "$states/konvaStage.svelte";
|
||||
import { textsState } from "$states/texts.svelte";
|
||||
import { fly } from "svelte/transition";
|
||||
import Download from "~icons/lucide/download";
|
||||
import StickyNote from "~icons/lucide/sticky-note";
|
||||
import Preview from "./Preview.svelte";
|
||||
import PreviewAll from "./PreviewAll.svelte";
|
||||
import PreviewControls from "./PreviewControls.svelte";
|
||||
|
||||
let current: number = $state(0);
|
||||
let direction: SlideDirectionType = $state("next");
|
||||
|
||||
let xDirection = $derived(
|
||||
direction == "next" ? PANEL_SETTINGS.PANEL_WIDTH : -PANEL_SETTINGS.PANEL_WIDTH,
|
||||
);
|
||||
|
||||
$effect(() => {
|
||||
if (textsState.texts.length === 0) {
|
||||
current = 0;
|
||||
} else {
|
||||
if (current > textsState.texts.length - 1) {
|
||||
current = textsState.texts.length - 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function downloadAll() {
|
||||
let downloadItems: Array<DownloadItem> = textsState.texts.map((text, idx) => ({
|
||||
filename: text.text,
|
||||
stage: konvaAllStagesState[idx]?.node,
|
||||
}));
|
||||
|
||||
downloadService.downloadAll(downloadItems);
|
||||
}
|
||||
|
||||
function downloadCurrent() {
|
||||
let node = konvaStageState.stage?.node;
|
||||
if (node) {
|
||||
downloadService.downloadPanel(node, textsState.texts[current].text);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#snippet panelTitle()}
|
||||
Панели <Badge text={textsState.texts.length} />
|
||||
{/snippet}
|
||||
|
||||
{#snippet panelControls()}
|
||||
<PreviewControls bind:current bind:direction max={textsState.texts.length} />
|
||||
{/snippet}
|
||||
|
||||
<Card title={panelTitle} titleSnippet={panelControls}>
|
||||
<div class="panel-viewer">
|
||||
<div class="panel-display">
|
||||
{#if textsState.texts.length}
|
||||
{#key current}
|
||||
{@const text = textsState?.texts[current]?.text}
|
||||
<div
|
||||
class="konva-wrapper"
|
||||
in:fly={{ x: xDirection, duration: TRANSITION_DURATION }}
|
||||
out:fly={{ x: -xDirection, duration: TRANSITION_DURATION }}
|
||||
>
|
||||
<Preview {text} bind:stage={konvaStageState.stage} />
|
||||
</div>
|
||||
{/key}
|
||||
{:else}
|
||||
<div class="empty-state" aria-label="Empty texts info">
|
||||
<StickyNote />
|
||||
<p>Добавьте тексты для создания панелей</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="panel-actions">
|
||||
<Button label="Скачать всё" ariaLabel="Download all" icon={Download} onclick={downloadAll} />
|
||||
<Button
|
||||
label="Скачать"
|
||||
ariaLabel="Download current"
|
||||
type="secondary"
|
||||
icon={Download}
|
||||
onclick={downloadCurrent}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<PreviewAll />
|
||||
|
||||
<style>
|
||||
.panel-viewer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.panel-display {
|
||||
background: var(--surface-subtle);
|
||||
border-radius: var(--radius);
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 150px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.panel-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 32px 16px;
|
||||
}
|
||||
|
||||
.empty-state :global(svg) {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin: 0 auto 12px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.konva-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user