mirror of
https://code.castopod.org/adaures/castopod
synced 2025-04-23 01:01:20 +00:00

- add "ActivityPub" library to handle server to server federation and basic client to server protocols using activitypub: - add webfinger endpoint to look for actor - add actor definition with inbox / outbox / followers - remote follow an actor - create notes with possible preview cards - interract with favourites, reblogs and replies - block incoming actors and/or domains - broadcast/schedule activities to fediverse followers using a cron task - For castopod, the podcast is the actor: - overwrite the activitypub library for castopod's specific needs - perform basic interactions administrating a podcast to interact with fediverse users: - create notes with episode attachment - favourite and share a note + reply - add specific castopod_namespaces for podcasts and episodes definitions - overwrite CodeIgniter's Route service to include alternate-content option for activitystream requests - update episode publication logic: - remove publication inputs in create / edit episode form - publish / schedule or unpublish an episode after creation - the podcaster publishes a note when publishing an episode - Javascript / Typescript modules: - fix Dropdown.ts to keep dropdown menu in foreground - add Modal.ts for funding links modal - add Toggler.ts to toggle various css states in ui - User Interface: - update tailwindcss to v2 - use castopod's pine and rose colors - update public layout to a 3 column layout - add pages in public for podcast activity, episode list and notes - update episode page to include linked notes - remove previous and next episodes from episode pages - show different public views depending on whether user is authenticated or not - use Kumbh Sans and Montserrat fonts - update CodeIgniter's config files - with CodeIgniter's new requirements, update docker environments are now based on php v7.3 image - move Image entity to Libraries - update composer and npm packages to latest versions closes #69 #65 #85, fixes #51 #91 #92 #88
84 lines
2.4 KiB
TypeScript
84 lines
2.4 KiB
TypeScript
import { createPopper, Instance, Placement } from "@popperjs/core";
|
|
|
|
const Dropdown = (): void => {
|
|
const dropdownButtons: NodeListOf<HTMLButtonElement> = document.querySelectorAll(
|
|
"[data-dropdown='button']"
|
|
);
|
|
|
|
for (let i = 0; i < dropdownButtons.length; i++) {
|
|
const button = dropdownButtons[i];
|
|
|
|
if (button.dataset.dropdownTarget) {
|
|
const menu: HTMLElement | null = document.getElementById(
|
|
button.dataset?.dropdownTarget
|
|
);
|
|
|
|
if (menu) {
|
|
// place the menu at then end of the body to prevent any overflow cuts
|
|
document.body.appendChild(menu);
|
|
|
|
let popperInstance: Instance | null = null;
|
|
|
|
const create = () => {
|
|
const offsetX = menu.dataset.dropdownOffsetX
|
|
? parseInt(menu.dataset.dropdownOffsetX)
|
|
: 0;
|
|
const offsetY = menu.dataset.dropdownOffsetY
|
|
? parseInt(menu.dataset.dropdownOffsetY)
|
|
: 0;
|
|
popperInstance = createPopper(button, menu, {
|
|
placement: menu.dataset.dropdownPlacement as Placement,
|
|
// strategy: "fixed",
|
|
modifiers: [
|
|
{
|
|
name: "offset",
|
|
options: {
|
|
offset: [offsetX, offsetY],
|
|
},
|
|
},
|
|
],
|
|
});
|
|
};
|
|
|
|
const destroy = () => {
|
|
if (popperInstance) {
|
|
popperInstance.destroy();
|
|
popperInstance = null;
|
|
}
|
|
};
|
|
|
|
const dropdownToggle = () => {
|
|
const isExpanded = menu.hasAttribute("data-show");
|
|
|
|
if (isExpanded) {
|
|
menu.removeAttribute("data-show");
|
|
button.setAttribute("aria-expanded", "false");
|
|
destroy();
|
|
} else {
|
|
menu.setAttribute("data-show", "");
|
|
button.setAttribute("aria-expanded", "true");
|
|
create();
|
|
}
|
|
};
|
|
|
|
// Toggle dropdown menu on button click event
|
|
button.addEventListener("click", dropdownToggle);
|
|
|
|
// Toggle off when clicking outside of dropdown
|
|
document.addEventListener("click", function (event) {
|
|
const isExpanded = menu.hasAttribute("data-show");
|
|
const isClickOutside =
|
|
!menu.contains(event.target as Node) &&
|
|
!button.contains(event.target as Node);
|
|
|
|
if (isExpanded && isClickOutside) {
|
|
dropdownToggle();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
export default Dropdown;
|