Skip to content

Commit

Permalink
Refactor web share api hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Flo0807 committed Aug 24, 2024
1 parent 541f4fb commit 88ae3a9
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 32 deletions.
4 changes: 2 additions & 2 deletions assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ import { LiveSocket } from "phoenix_live_view"
import topbar from "topbar"
import ThemeSwitch from "./hooks/themeSwitch"
import Copy from "./hooks/copy"
import ShareArticle from "./hooks/share_article"
import WebShareApi from "./hooks/webShareApi"

// Set the theme on page load
document.documentElement.setAttribute('data-theme', localStorage.getItem('theme') || 'night');

const Hooks = {
ThemeSwitch,
Copy,
ShareArticle
WebShareApi
}

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
Expand Down
27 changes: 0 additions & 27 deletions assets/js/hooks/share_article.js

This file was deleted.

75 changes: 75 additions & 0 deletions assets/js/hooks/webShareApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* ShareArticle Hook
*
* This hook provides functionality for sharing data using either the
* Web Share API or a fallback sharing mechanism.
*
* Usage:
* Add the `phx-hook="ShareArticle"` attribute to an element, and include
* `data-title` and `data-url` attributes with the corresponding title and URL.
*
* Example:
* <div phx-hook="ShareArticle" data-title="Article Title" data-url="https://example.com/article">
* <button data-share-web-share class="hidden">Share</button>
* <div data-share-fallback class="hidden">
* <!-- Fallback sharing options -->
* </div>
* </div>
*/
const WebShareApi = {
/**
* Initializes the sharing functionality when the element is mounted.
*/
mounted() {
const { title, url } = this.el.dataset;
const shareData = { title, url };

this.initializeSharing(shareData);
},
/**
* Sets up the appropriate sharing method based on browser support.
* @param {Object} shareData - The data to be shared (title and URL).
*/
initializeSharing(shareData) {
const webShareButton = this.el.querySelector("[data-share-web-share]");
const fallbackShareElement = this.el.querySelector("[data-share-fallback]");

if (navigator.share && navigator.canShare(shareData)) {
this.setupWebSharing(webShareButton, shareData);
} else {
this.setupFallbackSharing(webShareButton, fallbackShareElement);
}
},
/**
* Configures the Web Share API sharing functionality.
* @param {HTMLElement} webShareButton - The button element for sharing.
* @param {Object} shareData - The data to be shared.
*/
setupWebSharing(webShareButton, shareData) {
if (webShareButton) {
webShareButton.classList.remove("hidden");
webShareButton.addEventListener("click", async () => {
try {
await navigator.share(shareData);
} catch (err) {
console.error("Error sharing:", err);
}
});
}
},
/**
* Sets up the fallback sharing mechanism when native sharing is not supported.
* @param {HTMLElement} webShareButton - The Web Share API button to be hidden.
* @param {HTMLElement} fallbackElement - The fallback sharing element to be displayed.
*/
setupFallbackSharing(webShareButton, fallbackElement) {
if (webShareButton) {
webShareButton.classList.add("hidden");
}
if (fallbackElement) {
fallbackElement.classList.remove("hidden");
}
}
};

export default WebShareApi;
6 changes: 3 additions & 3 deletions lib/website_web/components/core_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,12 @@ defmodule WebsiteWeb.CoreComponents do

def share_article_dropdown(assigns) do
~H"""
<div id="share_container" phx-hook="ShareArticle" data-title={@title} data-url={@link}>
<button class="btn btn-ghost btn-sm btn-square" id="share_button">
<div id="share_container" phx-hook="WebShareApi" data-title={@title} data-url={@link}>
<button data-share-web-share class="btn btn-ghost btn-sm btn-square hidden">
<.icon name="hero-share" />
<span class="sr-only">Share</span>
</button>
<details id="share_dropdown" class="dropdown dropdown-end hidden">
<details id="share_dropdown" data-share-fallback class="dropdown dropdown-end hidden">
<summary
class="btn btn-ghost btn-sm btn-square"
phx-click-away={JS.remove_attribute("open", to: "#share_dropdown")}
Expand Down

0 comments on commit 88ae3a9

Please sign in to comment.