A rewrite of Poly+, my quality-of-life browser extension for Polytoria. Built entirely fresh using the WXT extension framework, Typescript, and with added better overall code quality.
extension
1import config from "@/utils/config.json";
2import { userDetails } from "@/utils/types";
3import * as apiTypes from "@/utils/api/types";
4const placeID = window.location.pathname.split('/')[3];
5
6/**
7 * Adds a button to the manage page of places allowing users to quickly download their place files from the website.
8 */
9export function placeFileExport() {
10 if (!config.api.enabled) {
11 throw new Error("[Poly+] API is disabled, cancelling place file export loading..");
12 };
13
14 const retrievePlaceFile = async function() {
15 const editReq: apiTypes.editApiSchema = (await (await fetch(config.api.urls.internal + 'places/edit/', {
16 method: 'POST',
17 body: JSON.stringify({
18 placeID: placeID
19 })
20 })).json());
21
22 if (!editReq.success) {
23 throw new Error("[Poly+] There was an error while retrieving the authenticated user's creator authorization token.");
24 };
25
26 const placeContents = (await (await fetch(`${config.api.urls.public}places/get-place?id=${placeID}&tokenType=creator`, {
27 headers: {
28 Authorization: editReq.token
29 }
30 })).blob());
31
32 return placeContents;
33 };
34
35 const container = document.createElement('div');
36 container.classList.add('form-group', 'mt-4');
37 container.innerHTML = `
38 <label class="mb-2">
39 <h5 class="mb-0">Download <code style="color: orange;">.poly</code> File</h5>
40 <small class="text-muted">Quickly download your place from the site!</small>
41 </label>
42 <br>
43 <button type="button" class="btn btn-primary">Download</button>
44 `;
45
46 const form = document.querySelector('form[action="/create/place/update"]')!;
47 const button = container.getElementsByTagName('button')[0]!;
48
49 form.insertBefore(container, form.children[form.children.length - 1]);
50
51 button.addEventListener('click', async () => {
52 button.innerHTML = `
53 <span class="spinner-grow spinner-grow-sm" aria-hidden="true"></span>
54 <span class="visually-hidden" role="status">Loading...</span>
55 `;
56
57 const placeContents = await retrievePlaceFile();
58 const blob = URL.createObjectURL(placeContents as any);
59 const link = document.createElement('a');
60
61 link.href = blob;
62 link.download = placeID + '.poly';
63 document.body.appendChild(link);
64 link.click();
65 link.remove();
66
67 button.textContent = 'Download';
68 });
69};