mirror of
https://github.com/jackyzha0/quartz.git
synced 2025-12-19 19:04:06 -06:00
feat:ReplyByEmail button
simplified and updated component
This commit is contained in:
parent
e8b3397f8c
commit
93aed112af
@ -2,17 +2,13 @@ import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } fro
|
|||||||
import { classNames } from "../util/lang"
|
import { classNames } from "../util/lang"
|
||||||
|
|
||||||
interface ReplyByEmailOptions {
|
interface ReplyByEmailOptions {
|
||||||
username?: string
|
email: string
|
||||||
domain?: string
|
|
||||||
includeTitles?: string[]
|
includeTitles?: string[]
|
||||||
excludeTitles?: string[]
|
excludeTitles?: string[]
|
||||||
buttonLabel?: string
|
buttonLabel?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default options will be used if not provided in the layout file
|
const defaultOptions: Partial<ReplyByEmailOptions> = {
|
||||||
const defaultOptions: ReplyByEmailOptions = {
|
|
||||||
username: "Y29udGFjdA==", // "contact" encoded in base64, as in contact@example.com
|
|
||||||
domain: "ZXhhbXBsZS5jb20=", // "example.com" encoded in base64, as in contact@example.com
|
|
||||||
includeTitles: [],
|
includeTitles: [],
|
||||||
excludeTitles: [],
|
excludeTitles: [],
|
||||||
buttonLabel: "Reply by email"
|
buttonLabel: "Reply by email"
|
||||||
@ -21,17 +17,15 @@ const defaultOptions: ReplyByEmailOptions = {
|
|||||||
const ReplyByEmail: QuartzComponent = ({
|
const ReplyByEmail: QuartzComponent = ({
|
||||||
fileData,
|
fileData,
|
||||||
displayClass,
|
displayClass,
|
||||||
username,
|
email,
|
||||||
domain,
|
|
||||||
includeTitles,
|
includeTitles,
|
||||||
excludeTitles,
|
excludeTitles,
|
||||||
buttonLabel
|
buttonLabel
|
||||||
}: QuartzComponentProps & ReplyByEmailOptions) => {
|
}: QuartzComponentProps & ReplyByEmailOptions) => {
|
||||||
const title = fileData.frontmatter?.title
|
const title = fileData.frontmatter?.title
|
||||||
|
|
||||||
// Use provided values or defaults
|
const encodedEmail = btoa(email)
|
||||||
const encodedPart1 = username || defaultOptions.username
|
|
||||||
const encodedPart2 = domain || defaultOptions.domain
|
|
||||||
const includeList = includeTitles || defaultOptions.includeTitles
|
const includeList = includeTitles || defaultOptions.includeTitles
|
||||||
const excludeList = excludeTitles || defaultOptions.excludeTitles
|
const excludeList = excludeTitles || defaultOptions.excludeTitles
|
||||||
const label = buttonLabel || defaultOptions.buttonLabel
|
const label = buttonLabel || defaultOptions.buttonLabel
|
||||||
@ -47,15 +41,22 @@ const ReplyByEmail: QuartzComponent = ({
|
|||||||
if (shouldDisplay) {
|
if (shouldDisplay) {
|
||||||
return (
|
return (
|
||||||
<div class="center-wrapper">
|
<div class="center-wrapper">
|
||||||
<button
|
<button
|
||||||
class={classNames(displayClass, "reply-by-email-button")}
|
class={classNames(displayClass, "reply-by-email-button")}
|
||||||
data-username={encodedPart1}
|
data-email={encodedEmail}
|
||||||
data-domain={encodedPart2}
|
data-title={encodeURIComponent(title)}
|
||||||
data-title={encodeURIComponent(title)}
|
onclick={`
|
||||||
|
const encodedEmail = this.getAttribute('data-email');
|
||||||
|
const email = atob(encodedEmail);
|
||||||
|
const title = this.getAttribute('data-title');
|
||||||
|
const mailtoLink = 'mailto:' + email + '?subject=' + title;
|
||||||
|
window.location.href = mailtoLink;
|
||||||
|
return false;
|
||||||
|
`}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return null
|
return null
|
||||||
@ -87,61 +88,22 @@ ReplyByEmail.css = `
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
// Script that works with SPA navigation
|
|
||||||
ReplyByEmail.beforeDOMLoaded = `
|
|
||||||
// Function to attach email button handlers
|
|
||||||
function attachEmailHandlers() {
|
|
||||||
document.querySelectorAll('.reply-by-email-button').forEach(function(button) {
|
|
||||||
// Remove existing event listeners first to prevent duplicates
|
|
||||||
button.removeEventListener('click', handleEmailButtonClick);
|
|
||||||
// Add fresh event listener
|
|
||||||
button.addEventListener('click', handleEmailButtonClick);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handler function for the email button click
|
|
||||||
function handleEmailButtonClick(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
// Get data attributes
|
|
||||||
const username = atob(this.getAttribute('data-username'));
|
|
||||||
const domain = atob(this.getAttribute('data-domain'));
|
|
||||||
const title = this.getAttribute('data-title');
|
|
||||||
|
|
||||||
// Create email address and mailto link
|
|
||||||
const email = username + '@' + domain;
|
|
||||||
const mailtoLink = 'mailto:' + email + '?subject=' + title;
|
|
||||||
|
|
||||||
// Open email client
|
|
||||||
window.location.href = mailtoLink;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initial attachment when the page loads
|
|
||||||
document.addEventListener('DOMContentLoaded', attachEmailHandlers);
|
|
||||||
|
|
||||||
// Re-attach handlers after SPA navigation
|
|
||||||
document.addEventListener('nav', function() {
|
|
||||||
// Small delay to ensure the new buttons are in the DOM
|
|
||||||
setTimeout(attachEmailHandlers, 10);
|
|
||||||
});
|
|
||||||
`
|
|
||||||
|
|
||||||
export default ((opts?: ReplyByEmailOptions) => {
|
export default ((opts?: ReplyByEmailOptions) => {
|
||||||
// Component constructor that accepts options
|
if (!opts?.email) {
|
||||||
|
throw new Error("ReplyByEmail component requires an email parameter")
|
||||||
|
}
|
||||||
|
|
||||||
const component: QuartzComponent = (props) => {
|
const component: QuartzComponent = (props) => {
|
||||||
return ReplyByEmail({
|
return ReplyByEmail({
|
||||||
...props,
|
...props,
|
||||||
username: opts?.username,
|
email: opts.email,
|
||||||
domain: opts?.domain,
|
|
||||||
includeTitles: opts?.includeTitles,
|
includeTitles: opts?.includeTitles,
|
||||||
excludeTitles: opts?.excludeTitles,
|
excludeTitles: opts?.excludeTitles,
|
||||||
buttonLabel: opts?.buttonLabel
|
buttonLabel: opts?.buttonLabel
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass through the CSS and beforeDOMLoaded
|
|
||||||
component.css = ReplyByEmail.css
|
component.css = ReplyByEmail.css
|
||||||
component.beforeDOMLoaded = ReplyByEmail.beforeDOMLoaded
|
|
||||||
|
|
||||||
return component
|
return component
|
||||||
}) satisfies QuartzComponentConstructor
|
}) satisfies QuartzComponentConstructor
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user