Skip to content

Commit

Permalink
Sibling Status Sync: Check or uncheck 'No more siblings' and have it …
Browse files Browse the repository at this point in the history
…apply to all siblings.
  • Loading branch information
shogenapps committed Dec 31, 2024
1 parent 8bd573a commit 338dc6a
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 16 deletions.
2 changes: 1 addition & 1 deletion scripts/create-feature.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ console.log("Feature creation complete.");
* - `-p` or `--pageTypes`: A comma-separated list of page types this feature applies to (e.g., `isProfilePage, isSpacePage`).
*
* **Important Notes**
* - **Page Types**: These are used to specify where the feature should be applied. Some important page types include `isProfilePage`, `isProfileEdit`, `isSpacePage`, `isSpaceEdit`, `isMainDomain`, etc. For more available page types, see `src/core/page_type.js`.
* - **Page Types**: These are used to specify where the feature should be applied. Some important page types include `isProfilePage`, `isProfileEdit`, `isSpacePage`, `isSpaceEdit`, `isMainDomain`, etc. For more available page types, see `src/core/pageType.js`.
* - **Categories**: The category helps to classify the feature in the extension. The available categories are:
* - `Global`
* - `Global/Style`
Expand Down
2 changes: 2 additions & 0 deletions src/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ import "./features/randomProfile/randomProfile";
import "./features/what_links_here/what_links_here";

/* MARKER: Default place for new features. Move these to a more appropriate place.*/
import "./features/sibling_status_sync/sibling_status_sync";

import "./features/space_watchlist_sorter/space_watchlist_sorter";

import "./features/help/help";
Expand Down
1 change: 1 addition & 0 deletions src/features/register_feature_options.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ import "./send_to_merge/send_to_merge_options";
import "./shareable_sources/shareable_sources_options";
import "./show_edits/show_edits_options";
import "./show_suggestions/show_suggestions_options";
import "./sibling_status_sync/sibling_status_sync_options";
import "./sort_theme_people/sort_theme_people_options";
import "./sourcepreview/sourcepreview_options";
import "./space_drafts/space_drafts_options";
Expand Down
1 change: 1 addition & 0 deletions src/features/sibling_status_sync/sibling_status_sync.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* Styles for siblingStatusSync feature */
150 changes: 150 additions & 0 deletions src/features/sibling_status_sync/sibling_status_sync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
Created By: Ian Beacall (Beacall-6)
Feature: Sibling Status Sync
*/

import $ from "jquery";
import { WikiTreeAPI } from "../../core/API/WikiTreeAPI";
import { shouldInitializeFeature } from "../../core/options/options_storage";

// Initialize the feature conditionally
shouldInitializeFeature("siblingStatusSync").then((result) => {
if (result) {
init();
}
});

// Main initialization function
function init() {
console.log("Initializing Sibling Status Sync feature...");
$("input[name='mNoSiblings']").on("change", async function () {
const isChecked = $(this).is(":checked");
const userId = getUserIdFromPage();
const siblings = await fetchSiblings(userId);

// Process siblings sequentially to avoid iframe conflicts
await updateSiblingsSequentially(siblings, isChecked);
});
}

// Extract User ID from the page URL
function getUserIdFromPage() {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get("u");
}

// Fetch sibling data using the WikiTree API
async function fetchSiblings(userId) {
const fields = ["Id", "Father", "Mother", "Name", "FirstName", "RealName", "mNoSiblings"];
const options = { nuclear: 1 };

const result = await WikiTreeAPI.getPeople("WBE-siblingStatusSync", [userId], fields, options);

const statusText = result[0];
const peopleList = result[2];

if (statusText) {
console.error("Error fetching people:", statusText);
return [];
}

const currentPerson = peopleList[userId];
const parentIds = [currentPerson.Father, currentPerson.Mother];

return Object.values(peopleList).filter(
(person) => person.Father === parentIds[0] && person.Mother === parentIds[1] && person.Id !== userId
);
}

// Process siblings sequentially
async function updateSiblingsSequentially(siblings, isChecked) {
for (const sibling of siblings) {
try {
//console.log(`Processing sibling ${sibling.Id}...`);
await updateSiblingPageWithIframe(sibling, isChecked);
//console.log(`Successfully updated sibling ${sibling.Id}`);
} catch (error) {
//console.error(`Failed to update sibling ${sibling.Id}:`, error);
}
}
}

// Update a sibling's edit page using an iframe
async function updateSiblingPageWithIframe(sibling, isChecked) {
return new Promise((resolve, reject) => {
const iframeId = `iframe-${sibling.Id}`;
const existingIframe = document.getElementById(iframeId);

// Remove any stale iframes
if (existingIframe) {
//console.warn(`Removing stale iframe for sibling ${sibling.Id}`);
document.body.removeChild(existingIframe);
}

const iframe = document.createElement("iframe");
iframe.id = iframeId;
iframe.style.display = "none";
iframe.src = `https://www.wikitree.com/index.php?title=Special:EditPerson&u=${sibling.Id}`;

let retries = 5;

const cleanUpAndReject = (error) => {
if (document.body.contains(iframe)) {
document.body.removeChild(iframe);
}
reject(error);
};

const processIframe = () => {
const iframeDoc = iframe.contentWindow.document;

const checkbox = iframeDoc.querySelector("input[name='mNoSiblings']");
const summaryField = iframeDoc.querySelector("#wpSummary");
const saveButton = iframeDoc.querySelector("#wpSave");

if (checkbox && summaryField && saveButton) {
checkbox.checked = isChecked;
checkbox.dispatchEvent(new Event("input", { bubbles: true }));

summaryField.value = isChecked ? "Checked 'No more siblings'" : "Unchecked 'No more siblings'";
summaryField.dispatchEvent(new Event("input", { bubbles: true }));

saveButton.click();

// console.log(`Sibling ${sibling.Id} updated successfully.`);
document.body.removeChild(iframe);

const $div = $("<div></div>");
$div.text(`Sibling ${sibling.FirstName || sibling.RealName || sibling.Name} updated.`);
$div.css({
position: "fixed",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
background: "white",
padding: "20px",
border: "1px solid black",
zIndex: 10000,
textAlign: "center",
fontSize: "16px",
borderRadius: "8px",
});
$("body").append($div);

setTimeout(() => $div.fadeOut(300, () => $div.remove()), 3000);
resolve();
} else if (retries > 0) {
retries -= 1;
// console.warn(`Retrying for sibling ${sibling.Id}, attempts left: ${retries}`);
setTimeout(processIframe, 1000);
} else {
cleanUpAndReject(new Error(`Failed to find required elements for sibling ${sibling.Id}`));
}
};

iframe.onload = processIframe;
iframe.onerror = () => cleanUpAndReject(new Error(`Failed to load iframe for sibling ${sibling.Id}`));

document.body.appendChild(iframe);
});
}
17 changes: 17 additions & 0 deletions src/features/sibling_status_sync/sibling_status_sync_options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
Created By: Ian Beacall (Beacall-6)
*/

import { registerFeature, OptionType } from "../../core/options/options_registry";
import { isProfileEdit } from "../../core/pageType";

registerFeature({
name: "Sibling Status Sync",
id: "siblingStatusSync",
description: "Check or uncheck 'No more siblings' and have it apply to all siblings.",
category: "Editing",
creators: [{ name: "Ian Beacall", wikitreeid: "Beacall-6" }],
contributors: [],
defaultValue: false,
pages: [isProfileEdit],
});
30 changes: 15 additions & 15 deletions src/features/space_watchlist_sorter/space_watchlist_sorter.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ async function loadSpaceWatchlist() {
});

if (response?.clientLogin?.result === "Success") {
console.log("Login successful:", response.clientLogin);
//console.log("Login successful:", response.clientLogin);
// Remove the authcode from the URL to clean it up
const cleanURL = window.location.href.split("?")[0];
window.history.replaceState({}, document.title, cleanURL);
Expand All @@ -217,7 +217,7 @@ async function loadSpaceWatchlist() {
const watchlist = await WikiTreeAPI.getSpaceWatchlist(appId, limit, fields);

if (watchlist.length === 0) {
console.log("No watchlist data. Redirecting to login...");
//console.log("No watchlist data. Redirecting to login...");
// Set redirecting flag in localStorage
localStorage.setItem("spaceWatchlistSorterRedirecting", "true");

Expand Down Expand Up @@ -262,26 +262,26 @@ async function loadWatchlistFromDB() {

getRequest.onsuccess = function () {
const result = getRequest.result || { unorganizedItems: [], folders: [] };
console.log("Watchlist loaded from IndexedDB:", result);
// console.log("Watchlist loaded from IndexedDB:", result);
resolve(result);
};

getRequest.onerror = function (e) {
console.error("Error reading from IndexedDB:", e.target.error);
// console.error("Error reading from IndexedDB:", e.target.error);
resolve({ unorganizedItems: [], folders: [] });
};
};

dbRequest.onerror = function (e) {
console.error("Error opening IndexedDB:", e.target.error);
//console.error("Error opening IndexedDB:", e.target.error);
resolve({ unorganizedItems: [], folders: [] });
};
});
}

async function populateInterface() {
try {
console.log("Populating interface...");
//console.log("Populating interface...");
const apiWatchlist = await loadSpaceWatchlist();
const dbWatchlist = await loadWatchlistFromDB();

Expand Down Expand Up @@ -350,7 +350,7 @@ async function populateInterface() {
}

async function saveWatchlistToDB() {
console.log("Saving watchlist to IndexedDB...");
//console.log("Saving watchlist to IndexedDB...");
const userId = await getUserWtId(); // Fetch the logged-in user's ID
if (!userId) {
console.error("Unable to fetch user ID. Cannot save watchlist.");
Expand Down Expand Up @@ -401,7 +401,7 @@ function addButton() {
console.log("Adding the sorter button...");
const clipboardContainer = $(".clipboardContainer");
if (clipboardContainer.find(".spaceWatchlistSorterButton").length === 0) {
console.log("Adding Space Watchlist Sorter button...");
//console.log("Adding Space Watchlist Sorter button...");
const sorterButton = $("<img>", {
title: "Space Watchlist Sorter",
class: "button small spaceWatchlistSorterButton",
Expand All @@ -412,10 +412,10 @@ function addButton() {
clipboardContainer.append(sorterButton);

sorterButton.on("click", async function () {
console.log("Sorter button clicked.");
//console.log("Sorter button clicked.");
const $popup = $("#spaceWatchlistSorter-popup");
if ($popup.length === 0) {
console.log("Appending popup and loading screen to body...");
//console.log("Appending popup and loading screen to body...");
$("body").append(`
<div id="spaceWatchlistSorter-loading" class="spaceWatchlistSorter-loading">
<img src="${chrome.runtime.getURL("images/tree.gif")}" alt="Loading..." />
Expand Down Expand Up @@ -460,7 +460,7 @@ function addButton() {
}

function addFolder() {
console.log("Adding a new folder...");
// console.log("Adding a new folder...");
const folderId = `spaceWatchlistSorterFolder-${Date.now()}`;
$("#spaceWatchlistSorterFolderContainer").append(`
<div id="${folderId}" class="spaceWatchlistSorter-folder">
Expand All @@ -476,7 +476,7 @@ function addFolder() {
initializeSortable(); // Reinitialize sortable for the new folder
initializeDroppable(); // Initialize droppable for the new folder

console.log(`Folder added with ID: ${folderId}`);
// console.log(`Folder added with ID: ${folderId}`);
}

function initializeDroppable() {
Expand Down Expand Up @@ -506,7 +506,7 @@ function initializeDroppable() {

shouldInitializeFeature("spaceWatchlistSorter").then((result) => {
if (result) {
console.log("Feature initialized.");
// console.log("Feature initialized.");
// Import CSS
import("./space_watchlist_sorter.css");

Expand Down Expand Up @@ -535,11 +535,11 @@ shouldInitializeFeature("spaceWatchlistSorter").then((result) => {
$(document).on("click", "#spaceWatchlistSorterClosePopup", function () {
saveWatchlistToDB();
$("#spaceWatchlistSorter-popup").hide();
console.log("Popup closed and data saved.");
// console.log("Popup closed and data saved.");
});
$(document).on("click", ".spaceWatchlistSorter-removeFolder", function () {
const folderId = $(this).closest(".spaceWatchlistSorter-folder").attr("id");
console.log(`Removing folder with ID: ${folderId}`);
// console.log(`Removing folder with ID: ${folderId}`);
$(this).closest(".spaceWatchlistSorter-folder").remove();
});
$(document).on("click", ".spaceWatchlistSorter-toggleFolder", function () {
Expand Down

0 comments on commit 338dc6a

Please sign in to comment.