From cba2e5a1c61de3f6ddeebfe8d68be7b532d0929a Mon Sep 17 00:00:00 2001 From: Struchkov Mark Date: Sun, 8 Sep 2024 14:30:35 +0300 Subject: [PATCH] _SocialShare.tsx --- quartz/components/_SocialShare.tsx | 77 +++ quartz/components/index.ts | 4 +- .../components/scripts/_socialshare.inline.ts | 498 +++++++++++++++++ quartz/components/styles/_socialshare.scss | 507 ++++++++++++++++++ quartz/util/theme.ts | 3 + 5 files changed, 1088 insertions(+), 1 deletion(-) create mode 100644 quartz/components/_SocialShare.tsx create mode 100644 quartz/components/scripts/_socialshare.inline.ts create mode 100644 quartz/components/styles/_socialshare.scss diff --git a/quartz/components/_SocialShare.tsx b/quartz/components/_SocialShare.tsx new file mode 100644 index 000000000..51c317bf4 --- /dev/null +++ b/quartz/components/_SocialShare.tsx @@ -0,0 +1,77 @@ +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" +// @ts-ignore +import script from "./scripts/_socialshare.inline" +import style from "./styles/_socialshare.scss.scss" + +const SocialShare: QuartzComponent = ({ displayClass, fileData }: QuartzComponentProps) => { + return ( +
+
+ + + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+ + + +
+
+ ) +} +RandomPageButton.css = style +RandomPageButton.afterDOMLoaded = script +export default (() => RandomPageButton) satisfies QuartzComponentConstructor diff --git a/quartz/components/index.ts b/quartz/components/index.ts index aeade816d..5828fd13d 100644 --- a/quartz/components/index.ts +++ b/quartz/components/index.ts @@ -26,6 +26,7 @@ import GithubSource from "./_GithubSource" import RandomPageButton from "./_RandomPageButton" import Ads from "./_Ads" import YandexMetrika from "./_YandexMetrika" +import SocialShare from "./_SocialShare" export { ArticleTitle, @@ -55,5 +56,6 @@ export { ScrollToTop, RandomPageButton, Ads, - YandexMetrika + YandexMetrika, + SocialShare } diff --git a/quartz/components/scripts/_socialshare.inline.ts b/quartz/components/scripts/_socialshare.inline.ts new file mode 100644 index 000000000..e1856f31f --- /dev/null +++ b/quartz/components/scripts/_socialshare.inline.ts @@ -0,0 +1,498 @@ +(function() { + function requireModule( + modules: { [key: string]: [Function, { [key: string]: string }] }, + cache: { [key: string]: { exports: any } }, + entry: number[] + ) { + function loadModule(moduleId: string): any { + if (!cache[moduleId]) { + if (!modules[moduleId]) { + const requireFn: (id: string, strict?: boolean) => any = + typeof require === 'function' && require; + if (requireFn) return requireFn(moduleId, true); + throw new Error(`Cannot find module '${moduleId}'`); + } + const module = (cache[moduleId] = { exports: {} }); + modules[moduleId][0].call( + module.exports, + (id: string) => loadModule(modules[moduleId][1][id] || id), + module, + module.exports, + requireModule, + modules, + cache, + entry + ); + } + return cache[moduleId].exports; + } + + for (const moduleId of entry) { + loadModule(moduleId.toString()); + } + } + + requireModule( + { + '1': [ + function (require: any, module: any, exports: any) { + 'use strict'; + + interface ShareOptions { + shareUrl: string; + params?: { [key: string]: string | number | boolean }; + isLink?: boolean; + width?: string; + height?: string; + } + + class Sharer { + elem: HTMLElement; + + constructor(t: HTMLElement) { + this.elem = t; + } + + static init() { + const elements = document.querySelectorAll('[data-sharer]'); + elements.forEach((element) => { + element.addEventListener('click', Sharer.add); + }); + } + + static add(event: Event) { + const target = (event.currentTarget || event.srcElement) as HTMLElement; + const sharer = new Sharer(target); + sharer.share(); + } + + getValue(attr: string): string | null { + const value = this.elem.getAttribute(`data-${attr}`); + if (value && attr === 'hashtag' && !value.startsWith('#')) { + return `#${value}`; + } + return value; + } + + share() { + const type = (this.getValue('sharer') || '').toLowerCase(); + const options: { [key: string]: ShareOptions } = { + facebook: { + shareUrl: 'https://www.facebook.com/sharer/sharer.php', + params: { + u: this.getValue('url') || '', + hashtag: this.getValue('hashtag') || '', + }, + }, + linkedin: { + shareUrl: "https://www.linkedin.com/shareArticle", + params: { + url: this.getValue("url"), + mini: true + } + }, + twitter: { + shareUrl: "https://twitter.com/intent/tweet/", + params: { + text: this.getValue("title"), + url: this.getValue("url"), + hashtags: this.getValue("hashtags"), + via: this.getValue("via") + } + }, + email: { + shareUrl: "mailto:" + this.getValue("to") || "", + params: { + subject: this.getValue("subject"), + body: this.getValue("title") + "\n" + this.getValue("url") + }, + isLink: true + }, + whatsapp: { + shareUrl: this.getValue("web") !== null ? "https://api.whatsapp.com/send" : "whatsapp://send", + params: { + text: this.getValue("title") + " " + this.getValue("url") + }, + isLink: true + }, + telegram: { + shareUrl: this.getValue("web") !== null ? "https://telegram.me/share" : "tg://msg_url", + params: { + text: this.getValue("title"), + url: this.getValue("url"), + to: this.getValue("to") + }, + isLink: true + }, + viber: { + shareUrl: "viber://forward", + params: { + text: this.getValue("title") + " " + this.getValue("url") + }, + isLink: true + }, + line: { + shareUrl: "http://line.me/R/msg/text/?" + encodeURIComponent(this.getValue("title") + " " + this.getValue("url")), + isLink: true + }, + pinterest: { + shareUrl: "https://www.pinterest.com/pin/create/button/", + params: { + url: this.getValue("url"), + media: this.getValue("image"), + description: this.getValue("description") + } + }, + tumblr: { + shareUrl: "http://tumblr.com/widgets/share/tool", + params: { + canonicalUrl: this.getValue("url"), + content: this.getValue("url"), + posttype: "link", + title: this.getValue("title"), + caption: this.getValue("caption"), + tags: this.getValue("tags") + } + }, + hackernews: { + shareUrl: "https://news.ycombinator.com/submitlink", + params: { + u: this.getValue("url"), + t: this.getValue("title") + } + }, + reddit: { + shareUrl: "https://www.reddit.com/submit", + params: { + url: this.getValue("url") + } + }, + vk: { + shareUrl: "http://vk.com/share.php", + params: { + url: this.getValue("url"), + title: this.getValue("title"), + description: this.getValue("caption"), + image: this.getValue("image") + } + }, + xing: { + shareUrl: "https://www.xing.com/app/user", + params: { + op: "share", + url: this.getValue("url"), + title: this.getValue("title") + } + }, + buffer: { + shareUrl: "https://buffer.com/add", + params: { + url: this.getValue("url"), + title: this.getValue("title"), + via: this.getValue("via"), + picture: this.getValue("picture") + } + }, + instapaper: { + shareUrl: "http://www.instapaper.com/edit", + params: { + url: this.getValue("url"), + title: this.getValue("title"), + description: this.getValue("description") + } + }, + pocket: { + shareUrl: "https://getpocket.com/save", + params: { + url: this.getValue("url") + } + }, + digg: { + shareUrl: "http://www.digg.com/submit", + params: { + url: this.getValue("url") + } + }, + stumbleupon: { + shareUrl: "http://www.stumbleupon.com/submit", + params: { + url: this.getValue("url"), + title: this.getValue("title") + } + }, + mashable: { + shareUrl: "https://mashable.com/submit", + params: { + url: this.getValue("url"), + title: this.getValue("title") + } + }, + mix: { + shareUrl: "https://mix.com/add", + params: { + url: this.getValue("url") + } + }, + flipboard: { + shareUrl: "https://share.flipboard.com/bookmarklet/popout", + params: { + v: 2, + title: this.getValue("title"), + url: this.getValue("url"), + t: Date.now() + } + }, + weibo: { + shareUrl: "http://service.weibo.com/share/share.php", + params: { + url: this.getValue("url"), + title: this.getValue("title"), + pic: this.getValue("image"), + appkey: this.getValue("appkey"), + ralateUid: this.getValue("ralateuid"), + language: "zh_cn" + } + }, + renren: { + shareUrl: "http://share.renren.com/share/buttonshare", + params: { + link: this.getValue("url") + } + }, + myspace: { + shareUrl: "https://myspace.com/post", + params: { + u: this.getValue("url"), + t: this.getValue("title"), + c: this.getValue("description") + } + }, + blogger: { + shareUrl: "https://www.blogger.com/blog-this.g", + params: { + u: this.getValue("url"), + n: this.getValue("title"), + t: this.getValue("description") + } + }, + baidu: { + shareUrl: "http://cang.baidu.com/do/add", + params: { + it: this.getValue("title"), + iu: this.getValue("url") + } + }, + douban: { + shareUrl: "https://www.douban.com/share/service", + params: { + name: this.getValue("title"), + href: this.getValue("url"), + image: this.getValue("image") + } + }, + okru: { + shareUrl: "https://connect.ok.ru/dk", + params: { + "st.cmd": "WidgetSharePreview", + "st.shareUrl": this.getValue("url"), + title: this.getValue("title") + } + }, + mailru: { + shareUrl: "http://connect.mail.ru/share", + params: { + share_url: this.getValue("url"), + linkname: this.getValue("title"), + linknote: this.getValue("description"), + type: "page" + } + }, + evernote: { + shareUrl: "http://www.evernote.com/clip.action", + params: { + url: this.getValue("url"), + title: this.getValue("title") + } + }, + skype: { + shareUrl: "https://web.skype.com/share", + params: { + url: this.getValue("url"), + title: this.getValue("title") + } + }, + quora: { + shareUrl: "https://www.quora.com/share", + params: { + url: this.getValue("url"), + title: this.getValue("title") + } + }, + delicious: { + shareUrl: "https://del.icio.us/post", + params: { + url: this.getValue("url"), + title: this.getValue("title") + } + }, + sms: { + shareUrl: "sms://", + params: { + body: this.getValue("body") + } + }, + trello: { + shareUrl: "https://trello.com/add-card", + params: { + url: this.getValue("url"), + name: this.getValue("title"), + desc: this.getValue("description"), + mode: "popup" + } + }, + messenger: { + shareUrl: "fb-messenger://share", + params: { + link: this.getValue("url") + } + }, + odnoklassniki: { + shareUrl: "https://connect.ok.ru/dk", + params: { + st: { + cmd: "WidgetSharePreview", + deprecated: 1, + shareUrl: this.getValue("url") + } + } + }, + meneame: { + shareUrl: "https://www.meneame.net/submit", + params: { + url: this.getValue("url") + } + }, + diaspora: { + shareUrl: "https://share.diasporafoundation.org", + params: { + title: this.getValue("title"), + url: this.getValue("url") + } + }, + googlebookmarks: { + shareUrl: "https://www.google.com/bookmarks/mark", + params: { + op: "edit", + bkmk: this.getValue("url"), + title: this.getValue("title") + } + }, + qzone: { + shareUrl: "https://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey", + params: { + url: this.getValue("url") + } + }, + refind: { + shareUrl: "https://refind.com", + params: { + url: this.getValue("url") + } + }, + surfingbird: { + shareUrl: "https://surfingbird.ru/share", + params: { + url: this.getValue("url"), + title: this.getValue("title"), + description: this.getValue("description") + } + }, + yahoomail: { + shareUrl: "http://compose.mail.yahoo.com", + params: { + to: this.getValue("to"), + subject: this.getValue("subject"), + body: this.getValue("body") + } + }, + wordpress: { + shareUrl: "https://wordpress.com/wp-admin/press-this.php", + params: { + u: this.getValue("url"), + t: this.getValue("title"), + s: this.getValue("title") + } + }, + amazon: { + shareUrl: "https://www.amazon.com/gp/wishlist/static-add", + params: { + u: this.getValue("url"), + t: this.getValue("title") + } + }, + pinboard: { + shareUrl: "https://pinboard.in/add", + params: { + url: this.getValue("url"), + title: this.getValue("title"), + description: this.getValue("description") + } + }, + threema: { + shareUrl: "threema://compose", + params: { + text: this.getValue("text"), + id: this.getValue("id") + } + } + // Add other share options here, similar to facebook + // ... + }; + + const option = options[type]; + if (option) { + option.width = this.getValue('width') || ''; + option.height = this.getValue('height') || ''; + this.urlSharer(option); + } + } + + urlSharer(option: ShareOptions) { + const params = option.params || {}; + const query = Object.keys(params) + .map((key) => `${key}=${encodeURIComponent(params[key])}`) + .join('&'); + + const url = `${option.shareUrl}${query ? `?${query}` : ''}`; + + if (!option.isLink) { + const width = option.width || '600'; + const height = option.height || '480'; + const left = window.innerWidth / 2 - parseInt(width) / 2 + window.screenX; + const top = window.innerHeight / 2 - parseInt(height) / 2 + window.screenY; + const windowFeatures = `scrollbars=no, width=${width}, height=${height}, top=${top}, left=${left}`; + const popup = window.open(url, '', windowFeatures); + if (window.focus) popup?.focus(); + } else { + window.location.href = url; + } + } + } + + if (document.readyState === 'complete' || document.readyState !== 'loading') { + Sharer.init(); + } else { + document.addEventListener('DOMContentLoaded', Sharer.init); + } + + window.addEventListener('page:load', Sharer.init); + window.addEventListener('turbolinks:load', Sharer.init); + (window as any).Sharer = Sharer; + }, + {}, + ], + }, + {}, + [1] + ); +})(); \ No newline at end of file diff --git a/quartz/components/styles/_socialshare.scss b/quartz/components/styles/_socialshare.scss new file mode 100644 index 000000000..4974920c5 --- /dev/null +++ b/quartz/components/styles/_socialshare.scss @@ -0,0 +1,507 @@ +a.share-icon { + border-bottom: 2px solid; +} + +.post-share { + + a.share-icon:hover { + background: white; + + .svg-social-icon { + background-image: var(--sprite-share-icon-color); + } + + } +} + +.share-link { + margin-top: 15px; + margin-right: 8px; + display: inline-block; + + a.share-telegram { + background: #2CA5E0; + border-color: #2CA5E0; + } + + a.share-twitter { + background: #1DA1F2; + border-color: #1DA1F2; + } + + a.share-vk { + background: #4680C2; + border-color: #4680C2; + } + + a.share-whatsapp { + background: #25D366; + border-color: #25D366; + } + + a.share-pocket { + background: #EF3F56; + border-color: #EF3F56; + } + + a.share-linkedin { + background: #0077B5; + border-color: #0077B5; + } + + a.share-viber { + background: #665CAC; + border-color: #665CAC; + } + + a.share-pinterest { + background: #BD081C; + border-color: #BD081C; + } + + a.share-tumblr { + background: #36465D; + border-color: #36465D; + } + + a.share-reddit { + background: #FF4500; + border-color: #FF4500; + } + + a.share-buffer { + background: #168EEA; + border-color: #168EEA; + } + + a.share-xing { + background: #006567; + border-color: #006567; + } + + a.share-line { + background: #00C300; + border-color: #00C300; + } + + a.share-instapaper { + background: #1F1F1F; + border-color: #1F1F1F; + } + + a.share-digg { + background: #000000; + border-color: #000000; + } + + a.share-stumbleupon { + background: #FD8235; + border-color: #FD8235; + } + + a.share-flipboard { + background: #E12828; + border-color: #E12828; + } + + a.share-weibo { + background: #20B8E5; + border-color: #20B8E5; + } + + a.share-renren { + background: #217DC6; + border-color: #217DC6; + } + + a.share-myspace { + background: #030303; + border-color: #030303; + } + + a.share-blogger { + background: #FF5722; + border-color: #FF5722; + } + + a.share-baidu { + background: #2319DC; + border-color: #2319DC; + } + + a.share-ok { + background: #EE8208; + border-color: #EE8208; + } + + a.share-evernote { + background: #00A82D; + border-color: #00A82D; + } + + a.share-skype { + background: #00AFF0; + border-color: #00AFF0; + } + + a.share-trello { + background: #0079BF; + border-color: #0079BF; + } + + a.share-mix { + background: #FF8126; + border-color: #FF8126; + } + + a.share-hackernews { + background: #FF8126; + border-color: #FF8126; + } + +} + +.share-text { + font-size: 30px; + margin-bottom: 10px; +} + +.share-icon { + border-radius: 6px; + padding: 10px 12px 4px 12px; + border: 2px solid; +} + +.svg-social-icon { + display: inline-block; + background-repeat: no-repeat; + background-image: var(--sprite-share-icon); + width: 20px; + height: 20px; +} + +.svg-social-icon-color { + display: inline-block; + background-repeat: no-repeat; + background-image: var(--sprite-share-icon-color); + width: 20px; + height: 20px; +} + +.icon-rss { + background-position: 0 0; +} + +.icon-mail-dot-ru { + background-position: -25px 0; +} + +.icon-udemy { + background-position: -50px 0; +} + +.icon-discord { + background-position: -75px 0; +} + +.icon-docker { + background-position: -100px 0; +} + +.icon-matrix { + background-position: -125px 0; +} + +.icon-xmpp { + background-position: -150px 0; +} + +.icon-gitea { + background-position: -175px 0; +} + +.icon-mastodon { + background-position: -200px 0; +} + +.icon-researchgate { + background-position: -225px 0; +} + +.icon-google { + background-position: 0 -25px; +} + +.icon-vine { + background-position: -25px -25px; +} + +.icon-wordpress { + background-position: -50px -25px; +} + +.icon-dribbble { + background-position: -75px -25px; +} + +.icon-behance { + background-position: -100px -25px; +} + +.icon-deviantart { + background-position: -125px -25px; +} + +.icon-jsfiddle { + background-position: -150px -25px; +} + +.icon-angellist { + background-position: -175px -25px; +} + +.icon-zhihu { + background-position: -200px -25px; +} + +.icon-strava { + background-position: -225px -25px; +} + +.icon-twitch { + background-position: 0 -50px; +} + +.icon-steam { + background-position: -25px -50px; +} + +.icon-patreon { + background-position: -50px -50px; +} + +.icon-kickstarter { + background-position: -75px -50px; +} + +.icon-foursquare { + background-position: -100px -50px; +} + +.icon-last-dot-fm { + background-position: -125px -50px; +} + +.icon-goodreads { + background-position: -150px -50px; +} + +.icon-500px { + background-position: -175px -50px; +} + +.icon-paypal { + background-position: -200px -50px; +} + +.icon-bandcamp { + background-position: -225px -50px; +} + +.icon-spotify { + background-position: 0 -75px; +} + +.icon-soundcloud { + background-position: -25px -75px; +} + +.icon-snapchat { + background-position: -50px -75px; +} + +.icon-xing { + background-position: -75px -75px; +} + +.icon-flickr { + background-position: -100px -75px; +} + +.icon-stackoverflow { + background-position: -125px -75px; +} + +.icon-bitbucket { + background-position: -150px -75px; +} + +.icon-freecodecamp { + background-position: -175px -75px; +} + +.icon-codepen { + background-position: -200px -75px; +} + +.icon-pinterest { + background-position: -225px -75px; +} + +.icon-keybase { + background-position: 0 -100px; +} + +.icon-quora { + background-position: -25px -100px; +} + +.icon-tumblr { + background-position: -50px -100px; +} + +.icon-youtube { + background-position: -75px -100px; +} + +.icon-gitlab { + background-position: -100px -100px; +} + +.icon-medium { + background-position: -125px -100px; +} + +.icon-instagram { + background-position: -150px -100px; +} + +.icon-linkedin { + background-position: -175px -100px; +} + +.icon-github { + background-position: -200px -100px; +} + +.icon-mixer { + background-position: -225px -100px; +} + +.icon-trello { + background-position: 0 -125px; +} + +.icon-skype { + background-position: -25px -125px; +} + +.icon-evernote { + background-position: -50px -125px; +} + +.icon-odnoklassniki { + background-position: -75px -125px; +} + +.icon-baidu { + background-position: -100px -125px; +} + +.icon-blogger { + background-position: -125px -125px; +} + +.icon-myspace { + background-position: -150px -125px; +} + +.icon-renren { + background-position: -175px -125px; +} + +.icon-sinaweibo { + background-position: -200px -125px; +} + +.icon-flipboard { + background-position: -225px -125px; +} + +.icon-digg { + background-position: 0 -150px; +} + +.icon-pocket { + background-position: -25px -150px; +} + +.icon-instapaper { + background-position: -50px -150px; +} + +.icon-line { + background-position: -75px -150px; +} + +.icon-xing1 { + background-position: -100px -150px; +} + +.icon-buffer { + background-position: -125px -150px; +} + +.icon-reddit { + background-position: -150px -150px; +} + +.icon-tumblr1 { + background-position: -175px -150px; +} + +.icon-pinterest1 { + background-position: -200px -150px; +} + +.icon-viber { + background-position: -225px -150px; +} + +.icon-linkedin1 { + background-position: 0 -175px; +} + +.icon-telegram { + background-position: -25px -175px; +} + +.icon-whatsapp { + background-position: -50px -175px; +} + +.icon-vk { + background-position: -100px -175px; +} + +.icon-twitter { + background-position: -125px -175px; +} + +.icon-leanpub { + width: 23px; + height: 20px; + background-position: 0 -200px; +} + +.icon-hacker-news { + width: 17px; + height: 20px; + background-position: -50px -200px; +} + +.icon-stumbleupon { + width: 21px; + height: 20px; + background-position: -75px -200px; +} diff --git a/quartz/util/theme.ts b/quartz/util/theme.ts index 9046cec66..f36b7de67 100644 --- a/quartz/util/theme.ts +++ b/quartz/util/theme.ts @@ -8,6 +8,7 @@ export interface ColorScheme { tertiary: string highlight: string textHighlight: string + shareIcon: string } interface Colors { @@ -51,6 +52,7 @@ ${stylesheet.join("\n\n")} --tertiary: ${theme.colors.lightMode.tertiary}; --highlight: ${theme.colors.lightMode.highlight}; --textHighlight: ${theme.colors.lightMode.textHighlight}; + --sprite-share-icon-color: ${theme.colors.lightMode.shareIcon}; --headerFont: "${theme.typography.header}", ${DEFAULT_SANS_SERIF}; --bodyFont: "${theme.typography.body}", ${DEFAULT_SANS_SERIF}; @@ -67,6 +69,7 @@ ${stylesheet.join("\n\n")} --tertiary: ${theme.colors.darkMode.tertiary}; --highlight: ${theme.colors.darkMode.highlight}; --textHighlight: ${theme.colors.darkMode.textHighlight}; + --sprite-share-icon: ${theme.colors.darkMode.shareIcon}; } ` }