Compare commits
13 Commits
943c301d9a
...
main
Author | SHA1 | Date | |
---|---|---|---|
1d4b4a30d1 | |||
d0d6d8ebc3 | |||
640712769e | |||
d17b4fe2d5 | |||
57ee2fa2ef | |||
3199b487b1 | |||
0f551af936 | |||
63e22059cf | |||
6a168a4b83 | |||
5107f68d4c | |||
18ead8b027 | |||
5822ced6af | |||
d8396abd36 |
@ -12,7 +12,7 @@ This plugin allow you to sell storage space to your users using Stripe subscript
|
|||||||
Payments are automated with Stripe.
|
Payments are automated with Stripe.
|
||||||
|
|
||||||
## Getting Started <a name = "getting_started"></a>
|
## Getting Started <a name = "getting_started"></a>
|
||||||
This is the NCD fork of the [peertube-plugin-orion-sell-storage](https://git.ncd-serv.fr/ncd/Peertube-plugins/src/branch/master/peertube-plugin-ncd-sell-storage) PeerTube plugin. This fork at inception allows you to add five packages rather than the original three. Everything else is pretty much left as-is, unless I decide to work on it more.
|
This is the NCD fork of the [peertube-plugin-orion-sell-storage](https://git.orion-serv.fr/ncd/Peertube-plugins/src/branch/master/peertube-plugin-ncd-sell-storage) PeerTube plugin. This fork at inception allows you to add five packages rather than the original three. Everything else is pretty much left as-is, unless I decide to work on it more.
|
||||||
Check [Prerequisites](#Prerequisites) to install this plugin
|
Check [Prerequisites](#Prerequisites) to install this plugin
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
@ -7,35 +7,45 @@ async function register({
|
|||||||
peertubeHelpers,
|
peertubeHelpers,
|
||||||
registerClientRoute,
|
registerClientRoute,
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add link admin page
|
* Add link admin page
|
||||||
*/
|
*/
|
||||||
|
|
||||||
registerHook({
|
registerHook({
|
||||||
target: "action:router.navigation-end",
|
target: "filter:left-menu.links.create.result",
|
||||||
handler: async (params) => {
|
handler: (links) => {
|
||||||
if (params.path.startsWith("/my-account")) {
|
if (!Array.isArray(links)) {
|
||||||
if (document.getElementById("ncd-subscription-link")) return;
|
return links;
|
||||||
|
|
||||||
let href = "/p/ncd-my-subscription";
|
|
||||||
|
|
||||||
// Get menu container
|
|
||||||
const menuContainer = document.getElementsByClassName("sub-menu")[0];
|
|
||||||
|
|
||||||
// Create link
|
|
||||||
const content = `
|
|
||||||
<a _ngcontent-dke-c79="" id="ncd-subscription-link" routerlinkactive="active" class="sub-menu-entry ng-star-inserted" href="${href}">
|
|
||||||
${await peertubeHelpers.translate("NCTV Storage")}
|
|
||||||
</a>
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Create node for it
|
|
||||||
const nodeLink = document.createElement("div");
|
|
||||||
nodeLink.innerHTML = content.trim();
|
|
||||||
|
|
||||||
// Insert to menu container
|
|
||||||
menuContainer.appendChild(nodeLink.firstChild);
|
|
||||||
}
|
}
|
||||||
|
let myLibraryLinks;
|
||||||
|
// Searching the 'in-my-library' entry.
|
||||||
|
for (const link of links) {
|
||||||
|
if (typeof link !== "object") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!("key" in link)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (link.key === "in-my-library" || link.key === "my-video-space") {
|
||||||
|
myLibraryLinks = link;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!myLibraryLinks) {
|
||||||
|
return links;
|
||||||
|
}
|
||||||
|
if (!Array.isArray(myLibraryLinks.links)) {
|
||||||
|
return links;
|
||||||
|
}
|
||||||
|
|
||||||
|
const label = "NCTV Storage";
|
||||||
|
myLibraryLinks.links.unshift({
|
||||||
|
label,
|
||||||
|
shortLabel: label,
|
||||||
|
path: "/p/ncd-my-subscription",
|
||||||
|
icon: "film",
|
||||||
|
});
|
||||||
|
return links;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -43,23 +53,23 @@ async function register({
|
|||||||
registerClientRoute({
|
registerClientRoute({
|
||||||
route: "ncd-my-subscription",
|
route: "ncd-my-subscription",
|
||||||
onMount: ({ rootEl }) => {
|
onMount: ({ rootEl }) => {
|
||||||
subPage.showPage({rootEl, peertubeHelpers});
|
subPage.showPage({ rootEl, peertubeHelpers });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
registerClientRoute({
|
registerClientRoute({
|
||||||
route: "ncd-subscription-success",
|
route: "ncd-subscription-success",
|
||||||
onMount: ({ rootEl }) => {
|
onMount: ({ rootEl }) => {
|
||||||
successPage.showPage({rootEl, peertubeHelpers});
|
successPage.showPage({ rootEl, peertubeHelpers });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
registerClientRoute({
|
registerClientRoute({
|
||||||
route: "ncd-subscription-cancel",
|
route: "ncd-subscription-cancel",
|
||||||
onMount: ({ rootEl }) => {
|
onMount: ({ rootEl }) => {
|
||||||
cancelPage.showPage({rootEl, peertubeHelpers});
|
cancelPage.showPage({ rootEl, peertubeHelpers });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export { register };
|
export { register };
|
||||||
|
@ -12,7 +12,7 @@ async function showPage({ rootEl, peertubeHelpers }) {
|
|||||||
const description = await peertubeHelpers.markdownRenderer.enhancedMarkdownToHTML(settings["sell-description"]);
|
const description = await peertubeHelpers.markdownRenderer.enhancedMarkdownToHTML(settings["sell-description"]);
|
||||||
const plans = [];
|
const plans = [];
|
||||||
|
|
||||||
for(let i = 1; i <= 5; i++) {
|
for (let i = 1; i <= 5; i++) {
|
||||||
const name = settings["plan-" + i + "-name"];
|
const name = settings["plan-" + i + "-name"];
|
||||||
const key = settings["plan-" + i + "-key"];
|
const key = settings["plan-" + i + "-key"];
|
||||||
const storage = settings["plan-" + i + "-storage"];
|
const storage = settings["plan-" + i + "-storage"];
|
||||||
@ -33,23 +33,25 @@ async function showPage({ rootEl, peertubeHelpers }) {
|
|||||||
headers: peertubeHelpers.getAuthHeader(),
|
headers: peertubeHelpers.getAuthHeader(),
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
// If have error
|
// If have error
|
||||||
if (!data || !data.status || (data.status && data.status !== "success")) {
|
if (!data || !data.status || (data.status && data.status !== "success")) {
|
||||||
peertubeHelpers.notifier.error(data.message || "Unknown error");
|
peertubeHelpers.notifier.error(data.message || "Unknown error");
|
||||||
}else{
|
} else {
|
||||||
session_id = data?.data?.session_id;
|
session_id = data?.data?.session_id;
|
||||||
sub_plan = data?.data?.sub_plan;
|
sub_plan = data?.data?.sub_plan;
|
||||||
}
|
}
|
||||||
|
|
||||||
rootEl.innerHTML = `
|
rootEl.innerHTML = `
|
||||||
<div class="ncd-content text-center">
|
<div class="ncd-content text-center">
|
||||||
<h1>${await peertubeHelpers.translate("Choose your Storage Plan")}</h1>
|
<h1>${await peertubeHelpers.translate("Choose your Storage Plan")}</h1>
|
||||||
<p>${description.length ? description : await peertubeHelpers.translate("You want tu spport us ? Or need more space ? Your in the right place!")}</p>
|
<h5><i>To subscribe to a storage plan with cryptocurrency (BTC, ETH, XMR), <a href="/about/contact">contact us</a>.</i></h5>
|
||||||
<div class="mt-5">
|
<h6><i>Note: Cryptocurrency prices are 25% higher to cover transaction fees.</i></h6>
|
||||||
|
<!-- <p>${description.length ? description : await peertubeHelpers.translate("You want tu spport us ? Or need more space ? Your in the right place!")}</p> -->
|
||||||
|
<div class="mt-5" style="max-width: 90%; margin: 0 auto;">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
${(await Promise.all(plans.map(async (plan) =>
|
${(await Promise.all(plans.map(async (plan) =>
|
||||||
`<div class="col-sm-12 col-md-6 col-lg-4" style="margin-bottom: 1rem;">
|
`<div class="col-sm-12 col-md-6 col-lg-4" style="margin-bottom: 1rem;">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form method="POST" action="#" class="ncdSubscriptionForm">
|
<form method="POST" action="#" class="ncdSubscriptionForm">
|
||||||
@ -65,22 +67,24 @@ async function showPage({ rootEl, peertubeHelpers }) {
|
|||||||
</div>
|
</div>
|
||||||
`))).join("")}
|
`))).join("")}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h4><i>NCTV also offers cryptocurrency subscriptions for media storage. Contact Matty on <a href="https://nicecrew.digital/@matty" target="_blank">NCD</a>, <a href="https://matrix.to/#/@matty:chat.nicecrew.digital" target="_blank">Matrix</a>, or via <a href="mailto:matty@nicecrew.digital">email</a>.</i></h4>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${session_id ? `
|
${session_id ? `
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
<form method="POST" action="#" id="formManageSub">
|
<form method="POST" action="#" id="formManageSub">
|
||||||
<input type="hidden" id="session-id" name="session_id" value="${session_id}" />
|
<input type="hidden" id="session-id" name="session_id" value="${session_id}" />
|
||||||
<button id="checkout-and-portal-button" type="submit" class="btn btn-primary">${await translate("Manage my Subscription")}</button>
|
<button id="checkout-and-portal-button" type="submit" class="btn btn-primary">${await translate("Manage my Subscription")}</button>
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
|
||||||
` : ""}
|
` : ""}
|
||||||
|
|
||||||
|
|
||||||
${sub_plan ? `
|
${sub_plan ? `
|
||||||
<p><i><b>${await translate("Your current plan")}</b>: ${sub_plan.name}, ${currency}${sub_plan.price} /${await peertubeHelpers.translate("month")}, ${sub_plan.storage} ${await peertubeHelpers.translate("GB Storage")}</i></p>
|
<p><i><b>${await translate("Your current plan")}</b>: ${sub_plan.name}, ${currency}${sub_plan.price} /${await peertubeHelpers.translate("month")}, ${sub_plan.storage} ${await peertubeHelpers.translate("GB Storage")}</i></p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a href="https://billing.stripe.com/p/login/aEUg0YcdE3ff9j2cMM" target="_blank" style="font-size: 1.25rem; background-color: #0083f5; color: white; border-radius: 0.25rem; padding: 0.5rem 0.75rem; margin-top: 1.25rem;">Manage Subcription</a>
|
||||||
|
<div>
|
||||||
` : ""}
|
` : ""}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -100,7 +104,7 @@ function listenSubmitSubscription(peertubeHelpers) {
|
|||||||
document.querySelectorAll(".ncdSubscriptionForm").forEach(el => {
|
document.querySelectorAll(".ncdSubscriptionForm").forEach(el => {
|
||||||
el.addEventListener("submit", (e) => {
|
el.addEventListener("submit", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const form = new URLSearchParams(new FormData(e.target));
|
const form = new URLSearchParams(new FormData(e.target));
|
||||||
fetch(baseUrl + "/create-checkout-session", {
|
fetch(baseUrl + "/create-checkout-session", {
|
||||||
@ -108,17 +112,17 @@ function listenSubmitSubscription(peertubeHelpers) {
|
|||||||
headers: peertubeHelpers.getAuthHeader(),
|
headers: peertubeHelpers.getAuthHeader(),
|
||||||
body: form,
|
body: form,
|
||||||
}).then((res) => res.json()).then((data) => {
|
}).then((res) => res.json()).then((data) => {
|
||||||
if(!data || !data.status || data.status !== "success") {
|
if (!data || !data.status || data.status !== "success") {
|
||||||
peertubeHelpers.notifier.error(data.message || "Unknown error");
|
peertubeHelpers.notifier.error(data.message || "Unknown error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.location.href = data.data.redirectUrl;
|
window.location.href = data.data.redirectUrl;
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
peertubeHelpers.notifier.error(err);
|
peertubeHelpers.notifier.error(err);
|
||||||
})
|
})
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
peertubeHelpers.notifier.error(error);
|
peertubeHelpers.notifier.error(error);
|
||||||
}
|
}
|
||||||
@ -137,17 +141,17 @@ function listenSubmitSubscription(peertubeHelpers) {
|
|||||||
headers: peertubeHelpers.getAuthHeader(),
|
headers: peertubeHelpers.getAuthHeader(),
|
||||||
body: form,
|
body: form,
|
||||||
}).then((res) => res.json()).then((data) => {
|
}).then((res) => res.json()).then((data) => {
|
||||||
if(!data || !data.status || data.status !== "success") {
|
if (!data || !data.status || data.status !== "success") {
|
||||||
peertubeHelpers.notifier.error(data.message || "Unknown error");
|
peertubeHelpers.notifier.error(data.message || "Unknown error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.location.href = data.data.redirectUrl;
|
window.location.href = data.data.redirectUrl;
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
peertubeHelpers.notifier.error(err);
|
peertubeHelpers.notifier.error(err);
|
||||||
})
|
})
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
peertubeHelpers.notifier.error(error);
|
peertubeHelpers.notifier.error(error);
|
||||||
}
|
}
|
||||||
|
2
main.js
2
main.js
@ -151,7 +151,7 @@ async function register({
|
|||||||
const INSTANCE_URL = "https://" + req.get('host');
|
const INSTANCE_URL = "https://" + req.get('host');
|
||||||
|
|
||||||
// For demonstration purposes, we're using the Checkout session to retrieve the customer ID.
|
// For demonstration purposes, we're using the Checkout session to retrieve the customer ID.
|
||||||
// Typically this is stored alongside the authenticated user in your database.
|
// Typically this is stored alongside the authenticated user in your database. (psql) users -> userID ->
|
||||||
const { session_id } = req.body;
|
const { session_id } = req.body;
|
||||||
const checkoutSession = await stripe.checkout.sessions.retrieve(session_id);
|
const checkoutSession = await stripe.checkout.sessions.retrieve(session_id);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user