diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..9ce75e4c9 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,44 @@ +name: Release Browser Extension +on: + push: + tags: + - v* + +jobs: + Publish: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: check that tag matches package.json version + run: | + pkg_version="v$(jq -r .version < package.json)" + if [[ "${{ github.ref_name }}" != "$pkg_version" ]]; then + echo "Tag ${{ github.ref_name }} does not match package.json version $pkg_version" >&2 + exit 1 + fi + + - uses: pnpm/action-setup@v3 + + - name: Use Node.js 19 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "pnpm" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build web + run: pnpm buildWebStandalone + + - name: Publish extension + run: | + cd dist/chromium-unpacked + pnpx chrome-webstore-upload-cli@2.1.0 upload --auto-publish + env: + EXTENSION_ID: ${{ secrets.CHROME_EXTENSION_ID }} + CLIENT_ID: ${{ secrets.CHROME_CLIENT_ID }} + CLIENT_SECRET: ${{ secrets.CHROME_CLIENT_SECRET }} + REFRESH_TOKEN: ${{ secrets.CHROME_REFRESH_TOKEN }} diff --git a/packages/discord-types/src/stores/StickerStore.d.ts b/packages/discord-types/src/stores/StickerStore.d.ts deleted file mode 100644 index 6ffee2726..000000000 --- a/packages/discord-types/src/stores/StickerStore.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { FluxStore } from ".."; - -export interface Sticker { - available: boolean; - description: string; - id: string; - name: string; - tags: string; - type: number; - t: "Sticker"; - format_type: number; - image: string; - title: string; - stickerPackId: StickerPackMeta["id"]; - guild_id: string; - filename?: string; - isAnimated?: boolean; -} - -export interface StickerPackMeta { - id: string; - title: string; - author?: { - name: string; - url?: string; - }; - logo: Sticker; - - dynamic?: DynamicStickerPackMeta["dynamic"]; -} - -export interface DynamicStickerPackMeta extends StickerPackMeta { - dynamic: { - version?: string; - refreshUrl: string; - authHeaders?: Record; - }; -} - -export interface StickerPack extends StickerPackMeta { - stickers: Sticker[]; -} - - -export interface StickerCategoryType { - id: string; - name: string; - iconUrl?: string; -} - -export class StickerStore extends FluxStore { - getStickerById(id: string): Sticker | undefined; - getStickerPack(id: string): StickerPack | undefined; - getPremiumPacks(): StickerPack[]; - isPremiumPack(id: string): boolean; - getRawStickersByGuild(): Map; - getAllStickersIterator(): IterableIterator; - getAllGuildStickers(): Map; - getStickersByGuildId(id: string): Sticker[] | undefined; -} diff --git a/packages/discord-types/src/stores/StickersStore.d.ts b/packages/discord-types/src/stores/StickersStore.d.ts index fdfb012c2..fd1d60fbd 100644 --- a/packages/discord-types/src/stores/StickersStore.d.ts +++ b/packages/discord-types/src/stores/StickersStore.d.ts @@ -2,10 +2,42 @@ import { FluxStore, GuildSticker, PremiumStickerPack, Sticker } from ".."; export type StickerGuildMap = Map; +export interface StickerPackMeta { + id: string; + title: string; + author?: { + name: string; + url?: string; + }; + logo: Sticker; + + dynamic?: DynamicStickerPackMeta["dynamic"]; +} + +export interface DynamicStickerPackMeta extends StickerPackMeta { + dynamic: { + version?: string; + refreshUrl: string; + authHeaders?: Record; + }; +} + +export interface StickerPack extends StickerPackMeta { + stickers: Sticker[]; +} + + +export interface StickerCategoryType { + id: string; + name: string; + iconUrl?: string; +} + export class StickersStore extends FluxStore { getAllGuildStickers(): StickerGuildMap; getRawStickersByGuild(): StickerGuildMap; getPremiumPacks(): PremiumStickerPack[]; + getAllStickersIterator(): IterableIterator; getStickerById(id: string): Sticker | undefined; getStickerPack(id: string): PremiumStickerPack | undefined; diff --git a/packages/discord-types/src/stores/index.d.ts b/packages/discord-types/src/stores/index.d.ts index 2c76af833..7a435ff5d 100644 --- a/packages/discord-types/src/stores/index.d.ts +++ b/packages/discord-types/src/stores/index.d.ts @@ -17,7 +17,6 @@ export * from "./TypingStore"; export * from "./UserProfileStore"; export * from "./UserStore"; export * from "./WindowStore"; -export * from "./StickerStore"; /** * React hook that returns stateful data for one or more stores diff --git a/src/equicordplugins/copyStickerLinks/index.tsx b/src/equicordplugins/copyStickerLinks/index.tsx deleted file mode 100644 index 13454c13d..000000000 --- a/src/equicordplugins/copyStickerLinks/index.tsx +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2025 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; -import { Devs } from "@utils/constants"; -import { copyWithToast } from "@utils/misc"; -import definePlugin from "@utils/types"; -import { Menu, React, StickerStore } from "@webpack/common"; -import { Promisable } from "type-fest"; - -interface Sticker { - t: "Sticker"; - format_type: number; - id: string; - type: number; -} - -const StickerExt = [, "png", "png", "json", "gif"] as const; - -function getUrl(data: Sticker) { - if (data.format_type === 4) - return `https:${window.GLOBAL_ENV.MEDIA_PROXY_ENDPOINT}/stickers/${data.id}.gif?size=4096&lossless=true`; - - return `https://${window.GLOBAL_ENV.CDN_HOST}/stickers/${data.id}.${StickerExt[data.format_type]}?size=4096&lossless=true`; -} - -function buildMenuItem(Sticker, fetchData: () => Promisable>) { - return ( - <> - - - { - const res = await fetchData(); - const data = { t: Sticker, ...res } as Sticker; - const url = getUrl(data); - copyWithToast(url, "Link copied!"); - } - } - /> - - { - const res = await fetchData(); - const data = { t: Sticker, ...res } as Sticker; - const url = getUrl(data); - VencordNative.native.openExternal(url); - } - } - /> - - ); -} - -const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => { - const { favoriteableId, favoriteableType } = props ?? {}; - if (!favoriteableId) return; - - const menuItem = (() => { - switch (favoriteableType) { - case "sticker": - const sticker = props.message.stickerItems.find(s => s.id === favoriteableId); - if (!sticker?.format_type) return; - return buildMenuItem("Sticker", () => props.message.stickerItems[0]); - } - })(); - - if (menuItem) - findGroupChildrenByChildId("devmode-copy-id", children, true)?.push(menuItem); -}; - -const expressionPickerPatch: NavContextMenuPatchCallback = (children, props: { target: HTMLElement; }) => { - const { id } = props?.target?.dataset ?? {}; - if (!id) return; - - if (!props.target.className?.includes("lottieCanvas")) { - const stickerCache = StickerStore.getStickerById(id); - if (stickerCache) { - const stickerInfo = { - format_type: stickerCache.format_type, - id: stickerCache.id, - type: stickerCache.type - }; - children.push(buildMenuItem("Sticker", () => stickerInfo)); - } - } -}; - -export default definePlugin({ - name: "CopyStickerLinks", - description: "Adds the ability to copy and open sticker links to your browser", - authors: [Devs.Byeoon], - contextMenus: { - "message": messageContextMenuPatch, - "expression-picker": expressionPickerPatch - } -}); diff --git a/src/equicordplugins/guildPickerDumper/index.tsx b/src/equicordplugins/guildPickerDumper/index.tsx index de0fddcb6..00063f5e6 100644 --- a/src/equicordplugins/guildPickerDumper/index.tsx +++ b/src/equicordplugins/guildPickerDumper/index.tsx @@ -9,7 +9,7 @@ import { migratePluginSettings } from "@api/Settings"; import { Devs, EquicordDevs } from "@utils/constants"; import definePlugin from "@utils/types"; import type { Guild } from "@vencord/discord-types"; -import { EmojiStore, Menu, StickerStore } from "@webpack/common"; +import { EmojiStore, Menu, StickersStore } from "@webpack/common"; import { zipSync } from "fflate"; const Patch: NavContextMenuPatchCallback = (children, { guild }: { guild: Guild; }) => { @@ -30,7 +30,7 @@ async function zipGuildAssets(guild: Guild, type: "emojis" | "stickers") { const isEmojis = type === "emojis"; const items = isEmojis ? EmojiStore.getGuilds()[guild.id]?.emojis - : StickerStore.getStickersByGuildId(guild.id); + : StickersStore.getStickersByGuildId(guild.id); if (!items) { return console.log("Server not found!"); diff --git a/src/equicordplugins/imagePreview/index.ts b/src/equicordplugins/imagePreview/index.ts index a3c8f6a46..065d8a392 100644 --- a/src/equicordplugins/imagePreview/index.ts +++ b/src/equicordplugins/imagePreview/index.ts @@ -9,7 +9,7 @@ import "./styles.css"; import { EquicordDevs } from "@utils/constants"; import { Logger } from "@utils/Logger"; import definePlugin from "@utils/types"; -import { StickerStore } from "@webpack/common"; +import { StickersStore } from "@webpack/common"; import { getMimeType, isLinkAnImage, settings, stripDiscordParams } from "./settings"; @@ -121,10 +121,10 @@ function loadImagePreview(url: string, sticker: boolean) { if (sticker) { const stickerId = url.split("/").pop()?.split(".")[0] ?? null; - const stickerData = stickerId ? StickerStore.getStickerById(stickerId) : null; + const stickerData = stickerId ? StickersStore.getStickerById(stickerId) : null; if (stickerData) { - switch (stickerData.type) { + switch (stickerData.format_type) { case 1: stickerType = "png"; break;