koboprice/lib/index.js

125 lines
2.7 KiB
JavaScript
Raw Normal View History

2024-07-14 22:36:08 +03:00
import "./logger";
import { initCache } from "./cache";
import { createElement, h, render } from "preact";
import { usePrices } from "./usePrices";
import { useCallback, useState } from "preact/hooks";
2024-07-14 16:49:40 +03:00
2024-07-14 22:36:08 +03:00
/*
TODO:
- more durable source for rates
2024-07-15 14:32:15 +03:00
- readme how to use and debug
2024-07-14 22:36:08 +03:00
*/
const createPricesContainer = () => {
2024-07-15 21:47:22 +03:00
const pricingActionContainers = document.querySelectorAll(".pricing-details");
l("all pricing containers", pricingActionContainers);
let visible;
for (const node of pricingActionContainers) {
if (node.checkVisibility()) {
l("found visible pricing container", node);
visible = node;
break;
}
}
2024-07-14 22:36:08 +03:00
return visible.parentNode.insertBefore(
document.createElement("div"),
visible,
);
2024-07-14 22:36:08 +03:00
};
const isInLibrary = () => document.querySelectorAll(".read-now").length;
const formatPrice = (countryPrice, convertedPrice) => {
if (countryPrice == undefined) {
return `LOADING`;
2024-07-14 22:36:08 +03:00
}
if (convertedPrice) {
return `${countryPrice} => ${convertedPrice?.formatted}`;
}
return `NOT FOUND`;
2024-07-14 22:36:08 +03:00
};
const Price = ({ props }) => {
const { convertedPrice, countryCode, countryPrice, url } = props;
const [isHovered, setHover] = useState(false);
const hover = useCallback(() => setHover(true));
const leave = useCallback(() => setHover(false));
const style = {
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
backgroundColor: isHovered ? "#d7d7d7" : "",
padding: "10px 10px 0 10px",
};
return h(
"a",
{
style,
href: url,
target: "_blank",
onMouseEnter: hover,
onMouseLeave: leave,
},
[
h("p", null, countryCode.toUpperCase()),
h(
"p",
{ style: { fontWeight: "bold" } },
formatPrice(countryPrice, convertedPrice),
),
],
2024-07-14 22:36:08 +03:00
);
};
2024-07-15 14:32:15 +03:00
const InLibrary = () =>
h(
"div",
{
style: {
display: "flex",
flexDirection: "column",
border: "1px solid black",
textAlign: "center",
},
},
h("h2", null, "Already in Library!"),
);
2024-07-14 22:36:08 +03:00
const Percent = (percent) => {
const style = { padding: "10px 10px 0 10px", textAlign: "center" };
2024-07-14 22:36:08 +03:00
if (percent == 100) return h("h2", { style }, "all prices are loaded!");
2024-07-14 16:49:40 +03:00
return h("h2", { style }, `${percent}%`);
};
2024-07-14 16:49:40 +03:00
const App = () => {
const [prices, percentChecked] = usePrices();
2024-07-14 16:49:40 +03:00
const style = {
display: "flex",
flexDirection: "column",
border: "1px solid black",
};
2024-07-14 16:49:40 +03:00
if (isInLibrary()) {
return InLibrary();
2024-07-14 16:49:40 +03:00
}
return h("div", { style }, [
Percent(percentChecked),
...prices.map((price) => h(Price, { props: price })),
]);
};
2024-07-14 16:49:40 +03:00
l("starting...");
initCache();
render(createElement(App), createPricesContainer());