improve: mobile UX
fix: some UX bugs
This commit is contained in:
parent
f1ecabd523
commit
e573c70497
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "aquavox",
|
||||
"version": "2.9.3",
|
||||
"version": "2.9.4",
|
||||
"private": false,
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
|
@ -35,7 +35,7 @@
|
||||
{#if $fileItems.length > 0}
|
||||
<AddIcon class="z-[1] relative text-3xl" />
|
||||
{:else}
|
||||
<ImportIcon class="z-[1] relative text-4xl" />
|
||||
<ImportIcon class="z-[1] relative text-4xl text-blue-500" />
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
|
@ -1,15 +1,3 @@
|
||||
<div class={$$props.class}>
|
||||
<svg width="1em" xmlns="http://www.w3.org/2000/svg" height="1em" fill="none" viewBox="0 0 12 17.2"
|
||||
><g style="mix-blend-mode: darken; fill: rgb(0, 0, 0);"
|
||||
><path
|
||||
d="M12.935 6.131v7.701c0 1.532-.636 2.168-2.169 2.168H2.168C.636 16 0 15.364 0 13.832V6.131c0-1.495.636-2.168 2.168-2.168h1.869v1.121H2.168c-.785 0-1.121.337-1.121 1.047v7.701c0 .822.336 1.159 1.121 1.159h8.598c.711 0 1.047-.337 1.047-1.159V6.131c0-.71-.336-1.047-1.047-1.047H8.897V3.963l1.889-.006c1.513.006 2.149.641 2.149 2.174Z"
|
||||
style="fill: rgb(0, 117, 255); fill-opacity: 1;"
|
||||
class="fills"
|
||||
/><path
|
||||
d="M6.505 11.607c.127 0 .205-.093.336-.205l3.028-2.991a.459.459 0 0 0 .112-.299c.019-.374-.223-.561-.523-.561-.206 0-.262.075-.299.113L7.178 9.645V.673C7.178.336 6.841 0 6.505 0c-.337 0-.673.336-.673.673v8.972L3.85 7.664a.404.404 0 0 0-.299-.113c-.266 0-.542.187-.523.561.008.169.056.243.112.299l3.028 2.991c.131.112.209.205.337.205Z"
|
||||
style="fill: rgb(0, 117, 255); fill-opacity: 1;"
|
||||
class="fills"
|
||||
/></g
|
||||
></svg
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M21 14a1 1 0 0 0-1 1v4a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-4a1 1 0 0 0-2 0v4a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-4a1 1 0 0 0-1-1m-9.71 1.71a1 1 0 0 0 .33.21a.94.94 0 0 0 .76 0a1 1 0 0 0 .33-.21l4-4a1 1 0 0 0-1.42-1.42L13 12.59V3a1 1 0 0 0-2 0v9.59l-2.29-2.3a1 1 0 1 0-1.42 1.42Z"/></svg>
|
||||
</div>
|
||||
|
@ -4,6 +4,7 @@
|
||||
import userAdjustingProgress from '../state/userAdjustingProgress';
|
||||
import progressBarSlideValue from '../state/progressBarSlideValue';
|
||||
import truncate from '../utils/truncate';
|
||||
import timestamp from '@core/utils/getCurrentTimestamp';
|
||||
|
||||
export let name: string;
|
||||
export let singer: string = '';
|
||||
@ -19,7 +20,7 @@
|
||||
export let hasLyrics: boolean;
|
||||
|
||||
export let showInteractiveBox: boolean;
|
||||
export let setShowingInteractiveBox: Function;
|
||||
export let showingInteractiveBoxUntil: Function;
|
||||
|
||||
let progressBar: HTMLDivElement;
|
||||
let volumeBar: HTMLDivElement;
|
||||
@ -29,12 +30,11 @@
|
||||
let songInfoTopContent: HTMLSpanElement;
|
||||
let userAdjustingVolume = false;
|
||||
let lastTouchClientX = 0;
|
||||
let mobileDeviceAdjustingProgress = false;
|
||||
|
||||
setTimeout(() => {
|
||||
if (screen.width < 728) {
|
||||
setShowingInteractiveBox(false);
|
||||
}
|
||||
}, 3000);
|
||||
if (screen.width < 728) {
|
||||
showingInteractiveBoxUntil(timestamp() + 3000);
|
||||
}
|
||||
|
||||
const mql = window.matchMedia('(max-width: 1280px)');
|
||||
|
||||
@ -81,27 +81,44 @@
|
||||
|
||||
window.addEventListener("mousemove", (event) => {
|
||||
if ($userAdjustingProgress) {
|
||||
adjustDisplayProgress(event.offsetX / progressBar.getBoundingClientRect().width);
|
||||
const x = event.clientX;
|
||||
const rec = progressBar.getBoundingClientRect();
|
||||
adjustDisplayProgress(truncate((x - rec.left) / rec.width,0,1));
|
||||
}
|
||||
});
|
||||
window.addEventListener("mouseup", (event) => {
|
||||
if ($userAdjustingProgress) {
|
||||
const x = event.clientX;
|
||||
const rec = progressBar.getBoundingClientRect();
|
||||
userAdjustingProgress.set(false);
|
||||
adjustProgress(event.offsetX / progressBar.getBoundingClientRect().width);
|
||||
adjustProgress(truncate((x - rec.left) / rec.width,0,1));
|
||||
}
|
||||
});
|
||||
window.addEventListener("touchmove", (event) => {
|
||||
if ($userAdjustingProgress) {
|
||||
adjustDisplayProgress((event.touches[0].clientX - progressBar.getBoundingClientRect().left) / progressBar.getBoundingClientRect().width);
|
||||
lastTouchClientX = event.touches[0].clientX;
|
||||
const x = event.touches[0].clientX;
|
||||
const rec = progressBar.getBoundingClientRect();
|
||||
adjustDisplayProgress(truncate((x - rec.left) / rec.width,0,1));
|
||||
lastTouchClientX = x;
|
||||
}
|
||||
});
|
||||
window.addEventListener("touchend", (event) => {
|
||||
if ($userAdjustingProgress) {
|
||||
adjustProgress((lastTouchClientX - progressBar.getBoundingClientRect().left) / progressBar.getBoundingClientRect().width);
|
||||
const x = lastTouchClientX;
|
||||
const rec = progressBar.getBoundingClientRect();
|
||||
adjustProgress(truncate((x - rec.left) / rec.width,0,1));
|
||||
userAdjustingProgress.set(false);
|
||||
mobileDeviceAdjustingProgress = false;
|
||||
}
|
||||
});
|
||||
|
||||
userAdjustingProgress.subscribe(()=> {
|
||||
showingInteractiveBoxUntil(timestamp() + 5000);
|
||||
});
|
||||
|
||||
function handleClick() {
|
||||
showingInteractiveBoxUntil(timestamp() + 5000);
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if showInfoTop}
|
||||
@ -112,11 +129,11 @@
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class={'absolute select-none bottom-12 h-60 w-[86vw] left-[7vw] duration-500 z-10 ' +
|
||||
class={'absolute select-none bottom-12 h-60 w-[86vw] left-[7vw] duration-500 z-10 transition-[opacity,transform] ' +
|
||||
(hasLyrics
|
||||
? 'lg:w-[76vw] lg:left-[12vw] xl:w-[37vw] xl:left-[7vw]'
|
||||
: 'lg:w-[76vw] lg:left-[12vw] xl:w-[37vw] xl:left-[31.5vw]') + ' ' +
|
||||
(showInteractiveBox ? 'opacity-100' : 'opacity-0')}
|
||||
(showInteractiveBox ? 'opacity-100' : 'opacity-0 translate-y-48')}
|
||||
style={`z-index: ${showInteractiveBox ? "0" : "50"}`}
|
||||
>
|
||||
|
||||
@ -132,12 +149,12 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="absolute w-full h-2/3 bottom-0" style={`z-index: ${showInteractiveBox ? "0" : "50"}`} on:click={() => {
|
||||
setShowingInteractiveBox(true);
|
||||
setTimeout(() => {
|
||||
setShowingInteractiveBox(false);
|
||||
}, 5000);
|
||||
}}></div>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div class={"absolute w-full h-2/3 bottom-0" + (showInteractiveBox ? '' : '-translate-y-48')}
|
||||
style={`z-index: ${showInteractiveBox ? "0" : "50"}`}
|
||||
on:click={handleClick}
|
||||
></div>
|
||||
|
||||
<div class="progress top-16">
|
||||
<div class="time-indicator text-shadow-md time-current">
|
||||
@ -148,7 +165,7 @@
|
||||
aria-valuemin="0"
|
||||
aria-valuenow={progress}
|
||||
bind:this={progressBar}
|
||||
class="progress-bar shadow-md"
|
||||
class="progress-bar shadow-md {mobileDeviceAdjustingProgress && '!h-[0.7rem]'}"
|
||||
on:keydown
|
||||
on:keyup
|
||||
on:click={(e) => {
|
||||
@ -159,11 +176,12 @@
|
||||
}}
|
||||
on:touchstart={() => {
|
||||
userAdjustingProgress.set(true);
|
||||
mobileDeviceAdjustingProgress = true;
|
||||
}}
|
||||
role="slider"
|
||||
tabindex="0"
|
||||
>
|
||||
<div class="bar" style={`width: ${(progress / (duration + 0.001)) * 100}%;`}></div>
|
||||
<div class="bar {mobileDeviceAdjustingProgress && '!h-[0.7rem]'}" style={`width: ${(progress / (duration + 0.001)) * 100}%;`}></div>
|
||||
</div>
|
||||
|
||||
<div class="time-indicator text-shadow-md time-total">{formatDuration(duration)}</div>
|
||||
@ -370,7 +388,7 @@
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.progress-bar:hover {
|
||||
.progress-bar:active {
|
||||
height: 0.7rem;
|
||||
}
|
||||
|
||||
@ -384,7 +402,7 @@
|
||||
transition: height 0.3s;
|
||||
}
|
||||
|
||||
.progress-bar:hover .bar {
|
||||
.progress-bar:active .bar {
|
||||
height: 0.7rem;
|
||||
}
|
||||
|
||||
@ -410,5 +428,11 @@
|
||||
.control-btn {
|
||||
transition: 0.1s
|
||||
}
|
||||
.progress-bar:hover {
|
||||
height: 0.7rem;
|
||||
}
|
||||
.progress-bar:hover .bar {
|
||||
height: 0.7rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -134,6 +134,11 @@
|
||||
};
|
||||
|
||||
|
||||
export const syncSpringWithDelta = (deltaY: number) => {
|
||||
const target = positionY + deltaY;
|
||||
springY!.setPosition(target);
|
||||
}
|
||||
|
||||
export const getInfo = () => {
|
||||
return {
|
||||
x: positionX,
|
||||
|
@ -116,6 +116,7 @@
|
||||
scrolling = true;
|
||||
currentLyricComponent.stop();
|
||||
currentLyricComponent.setY(currentY - deltaY);
|
||||
currentLyricComponent.syncSpringWithDelta(deltaY);
|
||||
}
|
||||
scrolling = true;
|
||||
if (scrollingTimeout) clearTimeout(scrollingTimeout);
|
||||
@ -250,23 +251,26 @@
|
||||
|
||||
{#if debugMode}
|
||||
<span
|
||||
class="text-white text-lg absolute z-50 px-2 py-0.5 m-2 rounded-3xl bg-white bg-opacity-20 backdrop-blur-lg right-0 font-mono">
|
||||
progress: {progress.toFixed(2)}, nextUpdate: {nextUpdate}, scrolling: {scrolling}, current: {currentLyricIndex}, uap: {$userAdjustingProgress}
|
||||
class="text-white text-lg absolute z-50 px-2 py-0.5 m-2 rounded-3xl bg-white bg-opacity-20 backdrop-blur-lg
|
||||
right-0 font-mono">
|
||||
progress: {progress.toFixed(2)}, nextUpdate: {nextUpdate}, scrolling: {scrolling}, current: {currentLyricIndex},
|
||||
uap: {$userAdjustingProgress}
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
{#if originalLyrics && originalLyrics.scripts}
|
||||
<div
|
||||
class="absolute top-[6.5rem] md:top-36 xl:top-0 w-screen xl:w-[52vw] px-6 md:px-12
|
||||
class={`absolute top-[6.5rem] md:top-36 xl:top-0 w-screen xl:w-[52vw] px-6 md:px-12 duration-500
|
||||
${showInteractiveBox ? "h-[calc(100vh-21rem)]" : "h-[calc(100vh-7rem)]"}
|
||||
lg:px-[7.5rem] xl:left-[46vw] xl:px-[3vw] xl:h-screen font-sans
|
||||
text-left no-scrollbar z-[1] pt-16 overflow-hidden"
|
||||
text-left no-scrollbar z-[1] pt-16 overflow-hidden`}
|
||||
style={`mask: linear-gradient(0deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 7%, rgba(0, 0, 0, 1) 95%,
|
||||
rgba(0, 0, 0, 0) 100%);
|
||||
height: ${showInteractiveBox ? "calc(100vh - 21rem)" : "calc(100vh - 7rem)"}`}
|
||||
rgba(0, 0, 0, 0) 100%);`}
|
||||
bind:this={lyricsContainer}
|
||||
>
|
||||
{#each lyricLines as lyric, i}
|
||||
<LyricLine line={lyric} index={i} bind:this={lyricComponents[i]} {debugMode} {lyricClick} {progress} {currentLyricIndex} {scrolling}/>
|
||||
<LyricLine line={lyric} index={i} bind:this={lyricComponents[i]} {debugMode} {lyricClick} {progress}
|
||||
{currentLyricIndex} {scrolling}/>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -4,8 +4,11 @@ export default function(key: string){
|
||||
"audio/ogg": "OGG 容器",
|
||||
"audio/flac": "FLAC 无损音频",
|
||||
"audio/aac": "AAC 音频",
|
||||
"audio/wav": "WAV 音频",
|
||||
"ttml": "TTML歌词",
|
||||
"lrc": "LRC 歌词"
|
||||
}
|
||||
if (!key) return "未知格式";
|
||||
if (!(key in dict)) return key;
|
||||
else return dict[key as keyof typeof dict];
|
||||
}
|
4
packages/core/utils/getCurrentTimestamp.ts
Normal file
4
packages/core/utils/getCurrentTimestamp.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export default function timestamp() {
|
||||
const ts = new Date().getTime();
|
||||
return ts;
|
||||
}
|
@ -2,12 +2,9 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/icon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<link rel="apple-touch-icon" href="/icon.png">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<title>AquaVox</title>
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
|
@ -67,8 +67,15 @@
|
||||
class="relative my-4 p-4 duration-150 bg-zinc-200 hover:bg-zinc-300 dark:bg-zinc-700 dark:hover:bg-zinc-600 rounded-lg"
|
||||
>
|
||||
<span class="font-bold">{musicList[id].name}</span> <br />
|
||||
<span>{toHumanSize(musicList[id].size)}</span> ·
|
||||
<a class="!no-underline" href={`/import/${id}/lyric`}>导入歌词</a>
|
||||
<div class="flex pt-0.5 items-center">
|
||||
<span class="w-[4.5rem]">{toHumanSize(musicList[id].size)}</span>
|
||||
<div class="!no-underline import inline-block cursor-default z-50 px-2 py-0.5 rounded ml-2
|
||||
hover:bg-gray-200 dark:hover:bg-zinc-500"
|
||||
onclick={(e) => {location.href = `/import/${id}/lyric`;e.stopPropagation();}}>
|
||||
导入歌词
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if musicList[id].coverUrl}
|
||||
<img
|
||||
class="h-16 w-16 object-cover absolute rounded-lg right-2 top-2"
|
||||
@ -95,7 +102,10 @@
|
||||
</div>
|
||||
|
||||
<style lang="postcss">
|
||||
a {
|
||||
@apply text-red-500 hover:text-red-400 duration-150 underline;
|
||||
.import {
|
||||
@apply text-red-500 duration-150 underline;
|
||||
}
|
||||
.import:hover {
|
||||
text-shadow: 0 0 3px rgba(239, 68, 68, 0.3);
|
||||
}
|
||||
</style>
|
||||
|
@ -14,6 +14,7 @@
|
||||
import progressBarRaw from '@core/state/progressBarRaw';
|
||||
import { parseTTML, parseLRC } from '@alikia/aqualyrics';
|
||||
import NewLyrics from '@core/components/lyrics/newLyrics.svelte';
|
||||
import timestamp from '@core/utils/getCurrentTimestamp';
|
||||
|
||||
const audioId = $page.params.id;
|
||||
let audioPlayer: HTMLAudioElement | null = null;
|
||||
@ -31,6 +32,7 @@
|
||||
let hasLyrics: boolean;
|
||||
const coverPath = writable('');
|
||||
let mainInterval: ReturnType<typeof setInterval>;
|
||||
let showInteractiveBoxUntil = Infinity;
|
||||
let showInteractiveBox = true;
|
||||
|
||||
function setMediaSession() {
|
||||
@ -197,8 +199,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
function setShowingInteractiveBox(showing: boolean) {
|
||||
showInteractiveBox = showing;
|
||||
function showingInteractiveBoxUntil(until: number) {
|
||||
showInteractiveBoxUntil = until;
|
||||
}
|
||||
|
||||
$: {
|
||||
@ -224,6 +226,10 @@
|
||||
|
||||
$: hasLyrics = !!originalLyrics;
|
||||
|
||||
setInterval(() => {
|
||||
showInteractiveBox = timestamp() < showInteractiveBoxUntil || screen.width > 728;
|
||||
}, 500);
|
||||
|
||||
readDB();
|
||||
</script>
|
||||
|
||||
@ -231,41 +237,45 @@
|
||||
<title>{name} - AquaVox</title>
|
||||
</svelte:head>
|
||||
|
||||
<Background coverId={audioId} />
|
||||
<Cover {coverPath} {hasLyrics} />
|
||||
<InteractiveBox
|
||||
{name}
|
||||
{singer}
|
||||
{duration}
|
||||
{volume}
|
||||
progress={currentProgress}
|
||||
clickPlay={playAudio}
|
||||
{paused}
|
||||
{adjustProgress}
|
||||
{adjustVolume}
|
||||
{adjustDisplayProgress}
|
||||
{hasLyrics}
|
||||
{showInteractiveBox}
|
||||
{setShowingInteractiveBox}
|
||||
/>
|
||||
<div class="select-none">
|
||||
|
||||
<NewLyrics {originalLyrics} progress={currentProgress} player={audioPlayer} {showInteractiveBox} />
|
||||
<Background coverId={audioId} />
|
||||
<Cover {coverPath} {hasLyrics} />
|
||||
<InteractiveBox
|
||||
{name}
|
||||
{singer}
|
||||
{duration}
|
||||
{volume}
|
||||
progress={currentProgress}
|
||||
clickPlay={playAudio}
|
||||
{paused}
|
||||
{adjustProgress}
|
||||
{adjustVolume}
|
||||
{adjustDisplayProgress}
|
||||
{hasLyrics}
|
||||
{showInteractiveBox}
|
||||
{showingInteractiveBoxUntil}
|
||||
/>
|
||||
|
||||
<audio
|
||||
bind:this={audioPlayer}
|
||||
controls
|
||||
style="display: none"
|
||||
on:play={() => {
|
||||
<NewLyrics {originalLyrics} progress={currentProgress} player={audioPlayer} {showInteractiveBox}/>
|
||||
|
||||
<audio
|
||||
bind:this={audioPlayer}
|
||||
controls
|
||||
style="display: none"
|
||||
on:play={() => {
|
||||
if (audioPlayer === null) return;
|
||||
paused = audioPlayer.paused;
|
||||
}}
|
||||
on:pause={() => {
|
||||
on:pause={() => {
|
||||
if (audioPlayer === null) return;
|
||||
paused = audioPlayer.paused;
|
||||
}}
|
||||
on:ended={() => {
|
||||
on:ended={() => {
|
||||
paused = true;
|
||||
if (audioPlayer == null) return;
|
||||
audioPlayer.pause();
|
||||
}}
|
||||
></audio>
|
||||
></audio>
|
||||
|
||||
</div>
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 9.5 KiB |
@ -1,16 +0,0 @@
|
||||
{
|
||||
"orientation": "portrait",
|
||||
"name": "AquaVox",
|
||||
"short_name": "AquaVox",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#000000",
|
||||
"description": "A readable Hacker News app",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/icon.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,11 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE svg
|
||||
PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="189.875" height="259.125">
|
||||
<g>
|
||||
<rect height="259.125" opacity="0" width="189.875" x="0" y="0"/>
|
||||
<path d="M20 259L56 259C69.375 259 76 252.375 76 239L76 20C76 6.25 69.375 0 56 0L20 0C6.625 0 0 6.75 0 20L0 239C0 252.375 6.625 259 20 259ZM133.875 259L169.875 259C183.25 259 189.875 252.375 189.875 239L189.875 20C189.875 6.25 183.25 0 169.875 0L133.875 0C120.5 0 113.875 6.75 113.875 20L113.875 239C113.875 252.375 120.5 259 133.875 259Z" fill="#ffffff" fill-opacity="0.85"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg width="255" xmlns="http://www.w3.org/2000/svg" height="259" id="screenshot-d13e393b-6a61-8076-8005-51e8b692555d" viewBox="-0 0 255 259" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1"><g xmlns:xlink="http://www.w3.org/1999/xlink" width="189.875" height="259.125" id="shape-d13e393b-6a61-8076-8005-51e8b692555d" data-testid="pause" style="fill: rgb(0, 0, 0);" ry="0" rx="0" version="1.1"><g id="shape-d13e393b-6a61-8076-8005-51e8b692d284" data-testid="base-background" style="display: none;"><g class="fills" id="fills-d13e393b-6a61-8076-8005-51e8b692d284"><rect width="255" height="259" x="0" transform="matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000)" style="fill: none;" ry="0" fill="none" rx="0" y="0"/></g></g><g id="shape-d13e393b-6a61-8076-8005-51e8b6933311" data-testid="svg-g" rx="0" ry="0" style="fill: rgb(0, 0, 0);"><g id="shape-d13e393b-6a61-8076-8005-51e8b6933312" data-testid="svg-rect" style="opacity: 0;"><g class="fills" id="fills-d13e393b-6a61-8076-8005-51e8b6933312"><rect rx="0" ry="0" x="0" y="0" transform="matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000)" width="215.19166666666672" height="259"/></g></g><g id="shape-d13e393b-6a61-8076-8005-51e8b693b101" data-testid="svg-path"><g class="fills" id="fills-d13e393b-6a61-8076-8005-51e8b693b101"><path d="M22.667,258.875L63.467,258.875C78.625,258.875,86.133,252.253,86.133,238.885L86.133,19.990C86.133,6.247,78.625,0.000,63.467,0.000L22.667,0.000C7.508,0.000,-0.000,6.747,-0.000,19.990L-0.000,238.885C-0.000,252.253,7.508,258.875,22.667,258.875ZL22.667,258.875ZM191.533,258.875L232.333,258.875C247.492,258.875,255.000,252.253,255.000,238.885L255.000,19.990C255.000,6.247,247.492,0.000,232.333,0.000L191.533,0.000C176.375,0.000,168.867,6.747,168.867,19.990L168.867,238.885C168.867,252.253,176.375,258.875,191.533,258.875ZL191.533,258.875Z" style="fill: rgb(255, 255, 255); fill-opacity: 0.85;"/></g></g></g></g></svg>
|
Before Width: | Height: | Size: 741 B After Width: | Height: | Size: 1.9 KiB |
Loading…
Reference in New Issue
Block a user