Huakun Shen e4d1441d73
Feature: support npm extension publish (#62)
* feat: npm package registry API

* refactor: move package registry files

* refactor: move jsr and npm api to a new package

* ci: add verify-package-export

* test: implement tests for npm package validation as kunkun extension

* chore: add missing dep for package-registry pkg

* feat: make provenance an optional input for npm validation function

* ci: add verify-package-export as dev dep to 2 packages that uses it

* feat: add rekor log API, and return commit from jsr & npm package in validation function

* feat: return github repo info from validation function of jsr and npm

* feat: extend ExtPublishMetadata to include optional GitHub repository details

* fix: eslint for ui package

* refactor: format desktop

* fix: eslint errors in desktop

* format: all code

* ci: add lint to CI

* feat: add more info to validation function returned from package-registry npm jsr

* pnpm lock

* feat: add 2 more variables to supabase extension metadata model

* format

* feat: add provenance card

* feat: add workflow path to ExtPublishMetadata and jsr/npm validation

* update provenance

* feat: make store extension and provenance more responsive

* chore: add globals to ui package

* fix: remove unnecessary any to fix eslint

* fix: svg sanitize

* chore: add @typescript-eslint/eslint-plugin to ui package to fix eslint

* fix: update eslint dep to fix error

* fix: try fixing eslint

* fix: update eslint configuration for improved compatibility

* chore: add globals package and update README for Discord invite

* fix: update eslint rules and upgrade typescript-eslint dependency

- Disabled additional eslint rules to resolve errors:
  - @typescript-eslint/no-unused-expressions
  - svelte/no-inner-declarations
- Upgraded typescript-eslint from version 8.19.1 to 8.20.0 for improved compatibility.

* update pnpm lock

---------

Co-authored-by: Huakun Shen <huaukun.shen@huakunshen.com>
2025-01-16 06:00:07 -05:00

90 lines
2.4 KiB
Svelte

<script lang="ts">
import { Button } from "@kksh/svelte5"
import { Layouts } from "@kksh/ui"
import { LogicalSize } from "@tauri-apps/api/dpi"
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"
import { CircleX } from "lucide-svelte"
import { onMount } from "svelte"
import * as clipboard from "tauri-plugin-clipboard-api"
let image = $state<string | null>(null)
const appWin = getCurrentWebviewWindow()
let originalSize = $state<{ width: number; height: number } | null>(null)
let originalScaleFactor = $state<number | null>(null)
let scale = $state<number>(1)
let currentSize = $derived(
originalSize ? { width: originalSize.width * scale, height: originalSize.height * scale } : null
)
$effect(() => {
if (currentSize) {
appWin.setSize(new LogicalSize(currentSize.width, currentSize.height))
}
})
async function getWindowSize() {
const size = await appWin.outerSize()
const scaleFactor = originalScaleFactor ?? (await appWin.scaleFactor())
const logicalSize = size.toLogical(scaleFactor)
return { logicalSize, scaleFactor }
}
onMount(async () => {
clipboard
.readImageBase64()
.then((b64) => {
image = b64
})
.finally(() => {
appWin.show()
})
const { logicalSize, scaleFactor } = await getWindowSize()
originalSize = { width: logicalSize.width, height: logicalSize.height }
originalScaleFactor = scaleFactor
})
async function onWheel(e: WheelEvent) {
scale += (e.deltaY < 0 ? 1 : -1) * 0.05
}
function onGestureChange(e: Event) {
e.preventDefault()
// eslint-disable-next-line @typescript-eslint/no-explicit-any
scale = (e as any).scale
}
$effect(() => {
document.addEventListener("wheel", onWheel)
document.addEventListener("gesturechange", onGestureChange)
return () => {
document.removeEventListener("wheel", onWheel)
document.removeEventListener("gesturechange", onGestureChange)
}
})
</script>
<svelte:window
on:keydown={(e) => {
if (e.key === "Escape") {
appWin.close()
}
}}
/>
<Button size="icon" variant="ghost" class="fixed left-2 top-2" onclick={() => appWin.close()}
><CircleX /></Button
>
<main class="z-50 h-screen w-screen overflow-hidden" data-tauri-drag-region>
{#if image}
<img
src={`data:image/png;base64,${image}`}
alt="screenshot"
class="pointer-events-none h-full w-full object-contain"
/>
{:else}
<Layouts.Center>
<p class="text-2xl font-bold">No image found in clipboard</p>
</Layouts.Center>
{/if}
</main>