From 2b1df595b4ee2fd3fe6bdcd36718dbd8b4ab9dad Mon Sep 17 00:00:00 2001 From: hiranya25 Date: Sun, 5 Apr 2026 20:26:30 +0530 Subject: [PATCH] feat: add discord support --- index.html | 4 +- src/social-share-button-preact.jsx | 28 ++++++------ src/social-share-button-qwik.tsx | 4 +- src/social-share-button-react.jsx | 70 +++++++++++++++--------------- src/social-share-button.js | 17 +++++++- 5 files changed, 69 insertions(+), 54 deletions(-) diff --git a/index.html b/index.html index 769407b..e78d693 100644 --- a/index.html +++ b/index.html @@ -680,7 +680,7 @@

Ready to Get Started?

container: "#demo-social", url: demoUrl, title: demoTitle, - platforms: ["facebook", "twitter", "reddit", "pinterest"], + platforms: ["facebook", "twitter", "reddit", "pinterest", "discord"], buttonText: "Share", }); @@ -689,7 +689,7 @@

Ready to Get Started?

container: "#demo-messaging", url: demoUrl, title: demoTitle, - platforms: ["whatsapp", "telegram"], + platforms: ["whatsapp", "telegram", "discord"], buttonText: "Share", }); diff --git a/src/social-share-button-preact.jsx b/src/social-share-button-preact.jsx index 012e66f..7bd81c9 100644 --- a/src/social-share-button-preact.jsx +++ b/src/social-share-button-preact.jsx @@ -1,13 +1,13 @@ import { useEffect, useRef } from "preact/hooks"; - /** - * SocialShareButton Preact Wrapper - * - * Provides a lightweight Preact functional component that wraps the core - * SocialShareButton vanilla JS library. Handles lifecycle, dynamic updates, - * and browser-only initialization. - * - */ +/** +* SocialShareButton Preact Wrapper +* +* Provides a lightweight Preact functional component that wraps the core +* SocialShareButton vanilla JS library. Handles lifecycle, dynamic updates, +* and browser-only initialization. +* +*/ export default function SocialShareButton({ url = "", @@ -15,7 +15,7 @@ export default function SocialShareButton({ description = "", hashtags = [], via = "", - platforms = ["whatsapp", "facebook", "twitter", "linkedin", "telegram", "reddit"], + platforms = ["whatsapp", "facebook", "twitter", "linkedin", "telegram", "reddit", "discord"], theme = "dark", buttonText = "Share", customClass = "", @@ -26,7 +26,7 @@ export default function SocialShareButton({ onCopy = null, buttonStyle = "default", modalPosition = "center", - + // Analytics props — the library emits events but never collects data itself. analytics = true, onAnalytics = null, // (payload) => void hook @@ -36,10 +36,10 @@ export default function SocialShareButton({ }) { // DOM reference to the container where the button will be injected const containerRef = useRef(null); - + // Reference to the vanilla JS class instance const shareButtonRef = useRef(null); - + // Storage for the latest options to avoid stale closures during async initialization const latestOptionsRef = useRef(null); @@ -97,7 +97,7 @@ export default function SocialShareButton({ }; // SSR Check: Ensure we're in a browser environment - if (typeof window === "undefined") return () => {}; + if (typeof window === "undefined") return () => { }; if (window.SocialShareButton) { // Core library is already loaded @@ -135,7 +135,7 @@ export default function SocialShareButton({ * Synchronizes prop changes from Preact down to the vanilla JS instance * without re-mounting the entire component. */ - + // Stringify array dependencies to prevent unnecessary re-runs when // parent components pass fresh array literals on every render. const hashtagsDep = JSON.stringify(hashtags); diff --git a/src/social-share-button-qwik.tsx b/src/social-share-button-qwik.tsx index bb54b19..9d467ea 100644 --- a/src/social-share-button-qwik.tsx +++ b/src/social-share-button-qwik.tsx @@ -19,7 +19,7 @@ interface Props { export const SocialShareButton = component$((props) => { const containerRef = useSignal(); - + useVisibleTask$(({ cleanup }) => { if (typeof window !== 'undefined' && (window as any).SocialShareButton && containerRef.value) { const shareButton = new (window as any).SocialShareButton({ @@ -29,7 +29,7 @@ export const SocialShareButton = component$((props) => { description: props.description || '', hashtags: props.hashtags || [], via: props.via || '', - platforms: props.platforms || ['whatsapp', 'facebook', 'twitter', 'linkedin', 'telegram', 'reddit'], + platforms: props.platforms || ['whatsapp', 'facebook', 'twitter', 'linkedin', 'telegram', 'reddit', 'discord'], theme: props.theme || 'dark', buttonText: props.buttonText || 'Share', customClass: props.customClass || '', diff --git a/src/social-share-button-react.jsx b/src/social-share-button-react.jsx index 24eb3b2..27ea699 100644 --- a/src/social-share-button-react.jsx +++ b/src/social-share-button-react.jsx @@ -13,7 +13,7 @@ export const SocialShareButton = ({ description = "", hashtags = [], via = "", - platforms = ["whatsapp", "facebook", "twitter", "linkedin", "telegram", "reddit", "pinterest"], + platforms = ["whatsapp", "facebook", "twitter", "linkedin", "telegram", "reddit", "pinterest", "discord"], theme = "dark", buttonText = "Share", customClass = "", @@ -21,7 +21,7 @@ export const SocialShareButton = ({ onCopy = null, buttonStyle = "default", modalPosition = "center", - + // Analytics: library emits events but never collects data analytics = true, onAnalytics = null, // Event callback @@ -31,7 +31,7 @@ export const SocialShareButton = ({ }) => { // DOM reference for the injection target const containerRef = useRef(null); - + // Reference to the vanilla JS class instance const shareButtonRef = useRef(null); @@ -46,39 +46,39 @@ export const SocialShareButton = ({ * Includes a safe check for the global SocialShareButton class. */ useEffect(() => { - if (containerRef.current && !shareButtonRef.current) { - if (typeof window !== "undefined" && window.SocialShareButton) { - shareButtonRef.current = new window.SocialShareButton({ - container: containerRef.current, - url: currentUrl, - title: currentTitle, - description, - hashtags, - via, - platforms, - theme, - buttonText, - customClass, - onShare, - onCopy, - buttonStyle, - modalPosition, - analytics, - onAnalytics, - analyticsPlugins, - componentId, - debug, - }); - } + if (containerRef.current && !shareButtonRef.current) { + if (typeof window !== "undefined" && window.SocialShareButton) { + shareButtonRef.current = new window.SocialShareButton({ + container: containerRef.current, + url: currentUrl, + title: currentTitle, + description, + hashtags, + via, + platforms, + theme, + buttonText, + customClass, + onShare, + onCopy, + buttonStyle, + modalPosition, + analytics, + onAnalytics, + analyticsPlugins, + componentId, + debug, + }); } + } - return () => { - if (shareButtonRef.current) { - shareButtonRef.current.destroy(); - shareButtonRef.current = null; - } - }; - }, []); + return () => { + if (shareButtonRef.current) { + shareButtonRef.current.destroy(); + shareButtonRef.current = null; + } + }; + }, []); /** * Update Effect @@ -86,7 +86,7 @@ export const SocialShareButton = ({ * Synchronizes React prop changes with the underlying vanilla JS instance * without re-mounting the entire component. */ - + useEffect(() => { if (shareButtonRef.current) { // Use the library's built-in update method diff --git a/src/social-share-button.js b/src/social-share-button.js index 3905128..ba95ce4 100644 --- a/src/social-share-button.js +++ b/src/social-share-button.js @@ -23,6 +23,7 @@ class SocialShareButton { "telegram", "reddit", "pinterest", + "discord", ], theme: options.theme || "dark", buttonText: options.buttonText || "Share", @@ -172,6 +173,11 @@ class SocialShareButton { color: "#E60023", icon: '', }, + discord: { + name: "Discord", + color: "#5865F2", + icon: '', + }, }; return this.options.platforms @@ -244,6 +250,7 @@ class SocialShareButton { reddit: `https://reddit.com/submit?url=${encodedUrl}&title=${encodedReddit}`, email: `mailto:?subject=${encodedTitle}&body=${encodedEmail}%20${encodedUrl}`, pinterest: `https://pinterest.com/pin/create/button/?url=${encodedUrl}&description=${encodedPinterest}`, + discord: "https://discord.com/channels/@me", }; return urls[platform] || ""; @@ -409,9 +416,17 @@ class SocialShareButton { if (shareUrl) { this._emit("social_share_click", "share", { platform }); - if (platform === "email") { + // Platform-specific sharing trigger logic: + // Discord does not provide a native web-share intent; therefore, the most reliable + // fallback is to copy the share URL to the clipboard and then navigate the user + // towards Discord's direct messaging area. + if (platform === "discord") { + this.copyLink(); + window.open(shareUrl, "_blank", "noopener,noreferrer"); + } else if (platform === "email") { window.location.href = shareUrl; } else { + // Default behavior: open platform's share intent in a specialized popup window window.open(shareUrl, "_blank", "noopener,noreferrer,width=600,height=600"); }