Compare commits
177 Commits
master
...
11d03746eb
Author | SHA1 | Date |
---|---|---|
|
11d03746eb | 6 months ago |
|
e0cdb2848f | 8 months ago |
|
cb738d9e11 | 8 months ago |
|
5fcd6b1957 | 8 months ago |
|
3b18a8a6e2 | 8 months ago |
|
52fea46702 | 8 months ago |
|
d237c3cc6d | 8 months ago |
|
65b13849b9 | 8 months ago |
|
0d67481109 | 8 months ago |
|
d2bce51941 | 8 months ago |
|
07d4433e25 | 8 months ago |
|
66604e987c | 8 months ago |
|
ca5d0bea60 | 8 months ago |
|
89a37d84b2 | 8 months ago |
|
fa64583de2 | 8 months ago |
|
6e24a983e2 | 8 months ago |
|
38158bd561 | 9 months ago |
|
ee7522671c | 9 months ago |
|
221aa7e0b4 | 9 months ago |
|
b51d511983 | 10 months ago |
|
16ee0077a5 | 10 months ago |
|
ef986724ef | 10 months ago |
|
5ce9136d89 | 10 months ago |
|
643e087404 | 11 months ago |
|
1b712bc1a0 | 1 year ago |
|
12db1d8719 | 1 year ago |
|
b4b906689f | 1 year ago |
|
d34cef391b | 1 year ago |
|
fe0e7bd63c | 1 year ago |
|
78f573af47 | 1 year ago |
|
12ed9a1799 | 1 year ago |
|
0b576b64e2 | 1 year ago |
|
708633d6b1 | 1 year ago |
|
59a2f65a33 | 1 year ago |
|
c069a9f799 | 1 year ago |
|
c634e15305 | 1 year ago |
|
a1404f7735 | 1 year ago |
|
70ec3ad09e | 1 year ago |
|
8a4c0bfa18 | 1 year ago |
|
00cc721344 | 1 year ago |
|
a917bdc34b | 1 year ago |
|
4648bc6f72 | 1 year ago |
|
5643314922 | 1 year ago |
|
89761743b8 | 1 year ago |
|
e01445b1d9 | 1 year ago |
|
5a37ea5a8e | 1 year ago |
|
1fdba77ae5 | 1 year ago |
|
7dd5e0fc8e | 1 year ago |
|
38a67cc2e2 | 1 year ago |
|
2c91a020bc | 1 year ago |
|
2a6f0c4a34 | 1 year ago |
|
f8d25d2c2a | 1 year ago |
|
b7e179c1fe | 1 year ago |
|
46feecee70 | 1 year ago |
|
9029344e1f | 1 year ago |
|
891fb00107 | 1 year ago |
|
640d3041ef | 1 year ago |
|
28469988dd | 1 year ago |
|
ac464be063 | 1 year ago |
|
c221805695 | 1 year ago |
|
49398566d3 | 1 year ago |
|
9ccc374feb | 1 year ago |
|
ad5c0abe14 | 1 year ago |
|
ff59c5a785 | 1 year ago |
|
93bcee9516 | 1 year ago |
|
f0c717ce5f | 1 year ago |
|
4f775b6be4 | 1 year ago |
|
436597a906 | 1 year ago |
|
e6120df550 | 1 year ago |
|
a4a0858110 | 1 year ago |
|
b1f4b1bff3 | 1 year ago |
|
814a27749a | 1 year ago |
|
a0cf440fac | 2 years ago |
|
d5e091e9af | 2 years ago |
|
5a5320b71c | 2 years ago |
|
7fe7339ea7 | 2 years ago |
|
3b6b8b96c4 | 2 years ago |
|
4c2a7aabe5 | 2 years ago |
|
3366c915e9 | 2 years ago |
|
db71bbf358 | 2 years ago |
|
7b77c0c884 | 2 years ago |
|
1478e72fcc | 2 years ago |
|
33384af5df | 2 years ago |
|
9d4dd64276 | 2 years ago |
|
e2f3929872 | 2 years ago |
|
4552c28e06 | 2 years ago |
|
214338b9f0 | 2 years ago |
|
cd9384adae | 2 years ago |
|
7469849c39 | 2 years ago |
|
0a63208da7 | 2 years ago |
|
0421c06d47 | 2 years ago |
|
7d767f840b | 2 years ago |
|
aa70c31950 | 2 years ago |
|
61509d1b1e | 2 years ago |
|
2b6974dcad | 2 years ago |
|
6594cdaa63 | 2 years ago |
|
b5cc8ec3ae | 2 years ago |
|
0fc86d5bfe | 2 years ago |
|
77f8537f61 | 2 years ago |
|
240bce92cd | 2 years ago |
|
9be1cc34ba | 2 years ago |
|
3336572a74 | 2 years ago |
|
fcf1c7b4b4 | 2 years ago |
|
c8e517828e | 2 years ago |
|
c44f2bbcd6 | 2 years ago |
|
6064e31c5d | 2 years ago |
|
97113bc5df | 2 years ago |
|
7f05730e9b | 2 years ago |
|
6ef591bdcc | 2 years ago |
|
6e43a7d23c | 2 years ago |
|
862a5a86e7 | 2 years ago |
|
f304fed1e9 | 2 years ago |
|
5ef3133f75 | 2 years ago |
|
0cfd263ef4 | 2 years ago |
|
94c96345e1 | 2 years ago |
|
ba808076ca | 2 years ago |
|
eaaa64dde8 | 2 years ago |
|
6b6558d924 | 2 years ago |
|
ecd5d78bc2 | 2 years ago |
|
a85c1d562c | 2 years ago |
|
2a71d425cd | 2 years ago |
|
381c4e7f82 | 2 years ago |
|
026dc263e5 | 2 years ago |
|
e15095d0dd | 2 years ago |
|
ad728d9046 | 2 years ago |
|
a6822d26bb | 2 years ago |
|
8065afc4d7 | 2 years ago |
|
a43623c5a5 | 2 years ago |
|
7a9bd70a09 | 2 years ago |
|
575ce2c65e | 2 years ago |
|
07853ed322 | 2 years ago |
|
aabd393e15 | 3 years ago |
|
1e65016d71 | 3 years ago |
|
2478d8b04e | 3 years ago |
|
2e2a261e3d | 3 years ago |
|
ee67b579c5 | 3 years ago |
|
6a77b27a42 | 3 years ago |
|
e77cd1d625 | 3 years ago |
|
f2f11f7f63 | 3 years ago |
|
7668321c98 | 3 years ago |
|
2cd6d336ba | 3 years ago |
|
ee45f689ac | 3 years ago |
|
7b0425c985 | 3 years ago |
|
7fa2dfecc6 | 3 years ago |
|
0d7d8e9f33 | 3 years ago |
|
f2b3d1e6b0 | 3 years ago |
|
6c2c0883ce | 3 years ago |
|
fdef990c6a | 3 years ago |
|
5fc9ef0bfb | 3 years ago |
|
b05a86b280 | 3 years ago |
|
5996954c4a | 3 years ago |
|
c82436cd8a | 3 years ago |
|
93049e9d52 | 3 years ago |
|
5f7494f134 | 3 years ago |
|
c1faeacee8 | 3 years ago |
|
6b272b9c99 | 3 years ago |
|
3dbe0d1e61 | 3 years ago |
|
cf4d3ee1bf | 3 years ago |
|
c9870a9d43 | 3 years ago |
|
09da927def | 3 years ago |
|
99de78b80e | 3 years ago |
|
d2456d5fea | 3 years ago |
|
855f36eeda | 3 years ago |
|
1b51b02483 | 3 years ago |
|
6c487f0c58 | 3 years ago |
|
fc3d7a7565 | 3 years ago |
|
8a8a9ad562 | 3 years ago |
|
d48b7a7d58 | 3 years ago |
|
5fdb5c554d | 3 years ago |
|
86cc4ce08d | 3 years ago |
|
c273560408 | 3 years ago |
|
0f3c667eb8 | 3 years ago |
|
bd5b3e8922 | 3 years ago |
|
aa1f2a1c3f | 3 years ago |
|
5e93ca3edb | 3 years ago |
|
f06ec18cd7 | 3 years ago |
|
804cf3abc5 | 3 years ago |
@ -0,0 +1,37 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: Deploy
|
||||
|
||||
steps:
|
||||
- name: submodules
|
||||
image: alpine/git
|
||||
commands:
|
||||
- git submodule update --init --recursive
|
||||
|
||||
- name: Build
|
||||
depends_on:
|
||||
- submodules
|
||||
image: node:12
|
||||
commands:
|
||||
- yarn
|
||||
- yarn build
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
|
||||
- name: Execute deploy script
|
||||
depends_on:
|
||||
- Build
|
||||
image: ubuntu:latest
|
||||
environment:
|
||||
SSH_KEY:
|
||||
from_secret: SSH_KEY
|
||||
commands:
|
||||
- apt update && apt install -y wget dos2unix openssh-client rsync
|
||||
- wget https://f.ruina.exposed/add-froth-key.sh && dos2unix ./add-froth-key.sh && chmod +x add-froth-key.sh && bash ./add-froth-key.sh
|
||||
- wget https://f.ruina.exposed/pleroma-fe-build-froth.sh && dos2unix ./pleroma-fe-build-froth.sh && chmod +x pleroma-fe-build-froth.sh && bash ./pleroma-fe-build-froth.sh
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
branch:
|
||||
- froth
|
@ -0,0 +1,9 @@
|
||||
[submodule "instance/pleroma-mods/pleroma-mod-syntax"]
|
||||
path = instance/pleroma-mods/pleroma-mod-syntax
|
||||
url = https://git.pleroma.social/absturztaube/pleroma-mod-syntax.git
|
||||
[submodule "instance/pleroma-mods/pleroma-mod-math"]
|
||||
path = instance/pleroma-mods/pleroma-mod-math
|
||||
url = https://git.pleroma.social/absturztaube/pleroma-mod-math
|
||||
[submodule "instance/pleroma-mods/pleroma-mod-imgsearch"]
|
||||
path = instance/pleroma-mods/pleroma-mod-imgsearch
|
||||
url = https://gitlab.com/SamTherapy/pleroma-mod-imgsearch
|
After Width: | Height: | Size: 1.2 MiB |
@ -0,0 +1,5 @@
|
||||
<div style="margin-left:12px; margin-right:12px">
|
||||
<center><p><a href="https://bloat.8777.ch">Epsilon Bloat FE</a> | <a href="https://tree.8777.ch">Sigma Treebird FE</a></p></center>
|
||||
<iframe width="100%" height="330" scrolling="no" frameborder="no" src="https://live.grumbulon.xyz/front/embed.html?&type=playlist&id=39"></iframe><br>
|
||||
<center><sub>brotip: you can close this dialog by enabling "Hide instance-specific panel" in the settings</sub></center><br>
|
||||
</div>
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"modDirectory": "/instance/pleroma-mods/",
|
||||
"mods": [
|
||||
"math",
|
||||
"syntax"
|
||||
]
|
||||
}
|
@ -0,0 +1,477 @@
|
||||
class PleromaModLoader {
|
||||
constructor () {
|
||||
this.config = {
|
||||
"modDirectory": "/instance/pleroma-mods/",
|
||||
"mods": []
|
||||
};
|
||||
this.loadConfig();
|
||||
this.loadedMods = {};
|
||||
this.classes = {};
|
||||
}
|
||||
|
||||
loadMods () {
|
||||
this.config.mods.forEach((mod) => {
|
||||
this.loadMod(mod);
|
||||
});
|
||||
}
|
||||
|
||||
loadMod (modName) {
|
||||
return PleromaModLoader.includeScript(
|
||||
this.config.modDirectory + "pleroma-mod-" + modName + "/mod.js"
|
||||
).then(() => {
|
||||
this.loadedMods[modName] = new this.classes[PleromaModLoader.getClassName(modName)]();
|
||||
});
|
||||
}
|
||||
|
||||
loadConfig () {
|
||||
window.fetch("/instance/pleroma-mod-config.json").then((response) => {
|
||||
return response.json();
|
||||
}).then((json) => {
|
||||
Object.keys(json).forEach((key) => {
|
||||
this.config[key] = json[key];
|
||||
});
|
||||
this.loadMods();
|
||||
}).catch((error) => {
|
||||
console.error("can't load loader config");
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
registerClass (className, object) {
|
||||
this.classes[className] = object;
|
||||
}
|
||||
|
||||
waitUntilReady () {
|
||||
const postPanel = document.querySelector(".status-container");
|
||||
const loginPanel = document.querySelector(".login-form");
|
||||
if (postPanel || loginPanel) {
|
||||
Object.keys(this.loadedMods).forEach((modName) => {
|
||||
const settings = document.querySelector(".settings-modal div[label]:first-child");
|
||||
if (settings) {
|
||||
if (!settings.querySelector(".mod-settings")) {
|
||||
this.appendModSettings(settings);
|
||||
}
|
||||
}
|
||||
|
||||
const mod = this.loadedMods[modName];
|
||||
if (mod.isEnabled) {
|
||||
mod.ready();
|
||||
}
|
||||
});
|
||||
|
||||
this.createObserver();
|
||||
} else {
|
||||
console.warn("not ready, trying again in 1s");
|
||||
window.setTimeout(() => { this.waitUntilReady(); }, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
createCheckbox (label, mod) {
|
||||
const labelElement = document.createElement("label");
|
||||
labelElement.classList.add("checkbox");
|
||||
|
||||
const input = document.createElement("input");
|
||||
input.setAttribute("type", "checkbox");
|
||||
input.checked = mod.isEnabled;
|
||||
input.addEventListener("change", (event) => {
|
||||
if (event.target.checked) {
|
||||
mod.enable();
|
||||
} else {
|
||||
mod.disable();
|
||||
}
|
||||
});
|
||||
labelElement.appendChild(input);
|
||||
|
||||
const fakeCheckbox = document.createElement("i");
|
||||
fakeCheckbox.classList.add("checkbox-indicator");
|
||||
labelElement.appendChild(fakeCheckbox);
|
||||
|
||||
const text = document.createElement("span");
|
||||
text.classList.add("label");
|
||||
text.innerText = label;
|
||||
labelElement.appendChild(text);
|
||||
|
||||
return labelElement;
|
||||
}
|
||||
|
||||
appendModSettings (element) {
|
||||
const container = document.createElement("div");
|
||||
container.classList.add("setting-item");
|
||||
container.classList.add("mod-settings");
|
||||
|
||||
const title = document.createElement("h2");
|
||||
title.innerText = "Pleroma Mods";
|
||||
container.appendChild(title);
|
||||
|
||||
const optionList = document.createElement("ul");
|
||||
optionList.classList.add("setting-list");
|
||||
|
||||
Object.keys(this.loadedMods).sort().forEach((modName) => {
|
||||
const li = document.createElement("li");
|
||||
|
||||
const enable = this.createCheckbox("enable " + modName, this.loadedMods[modName]);
|
||||
li.appendChild(enable);
|
||||
|
||||
const ulConfig = document.createElement("ul");
|
||||
ulConfig.classList.add("setting-list");
|
||||
|
||||
Object.keys(this.loadedMods[modName].config).forEach((key) => {
|
||||
if (key === "includes" || key === "filter") {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadedMods[modName].onSettingInit(key, ulConfig, document.createElement("li"));
|
||||
});
|
||||
|
||||
li.appendChild(ulConfig);
|
||||
|
||||
optionList.appendChild(li);
|
||||
});
|
||||
|
||||
container.appendChild(optionList);
|
||||
|
||||
element.appendChild(container);
|
||||
}
|
||||
|
||||
createObserver () {
|
||||
this.containers = {
|
||||
main: document.querySelector(".main"),
|
||||
notifications: document.querySelector(".notifications"),
|
||||
userPanel: document.querySelector(".user-panel"),
|
||||
settingsModal: document.querySelector(".settings-modal")
|
||||
};
|
||||
|
||||
const observerConfig = {
|
||||
subtree: true,
|
||||
childList: true
|
||||
};
|
||||
|
||||
this.observer = new MutationObserver((mutations, observer) => {
|
||||
const modal = document.querySelector(".settings-modal div[label]:first-child");
|
||||
if (modal && !modal.querySelector(".mod-settings")) {
|
||||
this.appendModSettings(modal);
|
||||
}
|
||||
|
||||
Object.values(this.loadedMods).forEach((mod) => {
|
||||
if (mod.isEnabled) {
|
||||
mutations.forEach((mutation) => {
|
||||
mod.mutate(mutation, observer);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.observer.observe(this.containers.main, observerConfig);
|
||||
if (this.containers.notifications) {
|
||||
this.observer.observe(this.containers.notifications, observerConfig);
|
||||
}
|
||||
if (this.containers.userPanel) {
|
||||
this.observer.observe(this.containers.userPanel, observerConfig);
|
||||
}
|
||||
if (this.containers.settingsModal) {
|
||||
this.observer.observe(this.containers.settingsModal, observerConfig);
|
||||
}
|
||||
}
|
||||
|
||||
static registerMod (mod) {
|
||||
window.__pleromaModLoader.registerClass(mod.name, mod);
|
||||
}
|
||||
|
||||
static includeScript (src) {
|
||||
console.log("include " + src);
|
||||
return new Promise((resolve) => {
|
||||
const script = document.createElement("script");
|
||||
script.setAttribute("src", src);
|
||||
script.setAttribute("type", "text/javascript");
|
||||
script.onload = () => {
|
||||
resolve();
|
||||
};
|
||||
document.querySelector("body").appendChild(script);
|
||||
});
|
||||
}
|
||||
|
||||
static includeCss (src) {
|
||||
console.log("include " + src);
|
||||
return new Promise((resolve) => {
|
||||
const link = document.createElement("link");
|
||||
link.setAttribute("href", src);
|
||||
link.setAttribute("rel", "stylesheet");
|
||||
link.setAttribute("type", "text/css");
|
||||
link.onload = () => {
|
||||
resolve();
|
||||
};
|
||||
document.querySelector("head").appendChild(link);
|
||||
});
|
||||
}
|
||||
|
||||
static excludeScript (src) {
|
||||
return new Promise((resolve) => {
|
||||
const script = document.querySelector("script[src=\"" + src + "\"]");
|
||||
if (script) {
|
||||
script.remove();
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
static excludeCss (src) {
|
||||
return new Promise((resolve) => {
|
||||
const link = document.querySelector("link[href=\"" + src + "\"]");
|
||||
if (link) {
|
||||
link.remove();
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
static getVueScope (element) {
|
||||
if (!element) {
|
||||
return null;
|
||||
}
|
||||
if (element.__vue__) {
|
||||
console.warn("old vue version, please update pleroma-fe");
|
||||
return element.__vue__;
|
||||
}
|
||||
if (element._vnode) {
|
||||
return element._vnode;
|
||||
}
|
||||
if (element.__vnode) {
|
||||
return element.__vnode;
|
||||
}
|
||||
if (element.parentNode) {
|
||||
return PleromaModLoader.getVueScope(element.parentNode);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static getVueComponent (element) {
|
||||
if (!element) {
|
||||
return null;
|
||||
}
|
||||
if (element.__vnode && element.__vnode.component) {
|
||||
return element.__vnode.component;
|
||||
}
|
||||
if (element.__vueParentComponent) {
|
||||
return element.__vueParentComponent.ctx;
|
||||
}
|
||||
if (element.__vueComponent__) {
|
||||
return element.__vueComponent__;
|
||||
}
|
||||
if (element.parentNode) {
|
||||
return PleromaModLoader.getVueComponent(element.parentNode);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static getRootVueScope () {
|
||||
return PleromaModLoader.getVueScope(document.querySelector("#app"));
|
||||
}
|
||||
|
||||
static getToken () {
|
||||
return PleromaModLoader.getRootVueScope().appContext.provides.store.getters.getUserToken();
|
||||
}
|
||||
|
||||
static getModDir () {
|
||||
return window.__pleromaModLoader.config.modDirectory;
|
||||
}
|
||||
|
||||
static getClassName (name) {
|
||||
let className = "PleromaMod";
|
||||
name.split("-").forEach((namePart) => {
|
||||
className += namePart.substring(0, 1).toUpperCase();
|
||||
className += namePart.substring(1);
|
||||
});
|
||||
return className;
|
||||
}
|
||||
|
||||
static api (method, path, params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const token = PleromaModLoader.getToken();
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.responseType = "json";
|
||||
xhr.open(method, path);
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.setRequestHeader("Authorization", "Bearer " + token);
|
||||
xhr.onreadstatechange = () => {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status !== 200) {
|
||||
reject(new Error({
|
||||
status: xhr.status,
|
||||
response: xhr.response,
|
||||
xhr: xhr
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.onload = () => {
|
||||
resolve(xhr.response);
|
||||
};
|
||||
xhr.send(JSON.stringify(params));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class PleromaMod { // eslint-disable-line no-unused-vars
|
||||
constructor (name) {
|
||||
this.name = name;
|
||||
this.config = {};
|
||||
this.isRunning = false;
|
||||
}
|
||||
|
||||
get isEnabled () {
|
||||
return localStorage.getItem("pleroma_mod_" + this.name + "_enabled") !== "false" || true;
|
||||
}
|
||||
|
||||
getClassName () {
|
||||
return PleromaModLoader.getClassName(this.name);
|
||||
}
|
||||
|
||||
getModDir () {
|
||||
return PleromaModLoader.getModDir() + this.name + "/";
|
||||
}
|
||||
|
||||
ready () {
|
||||
this.onReady();
|
||||
this.run();
|
||||
}
|
||||
|
||||
destroy () {
|
||||
this.isRunning = false;
|
||||
if (this.config.includes) {
|
||||
const styles = this.config.includes.css || [];
|
||||
const scripts = this.config.includes.js || [];
|
||||
|
||||
Promise.all(styles.map((style) => {
|
||||
return this.excludeCss(style);
|
||||
}).concat(scripts.map((script) => {
|
||||
return this.excludeScript(script);
|
||||
}))).then(() => {
|
||||
this.onDestroy();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.onDestroy();
|
||||
}
|
||||
|
||||
run () {
|
||||
if (this.config.includes) {
|
||||
const styles = this.config.includes.css || [];
|
||||
const scripts = this.config.includes.js || [];
|
||||
|
||||
Promise.all(styles.map((style) => {
|
||||
return this.includeCss(style);
|
||||
}).concat(scripts.map((script) => {
|
||||
return this.includeScript(script);
|
||||
})).concat([
|
||||
this.loadConfig(),
|
||||
this.onCreate()
|
||||
])).then(() => {
|
||||
this.isRunning = true;
|
||||
this.onRun();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.isRunning = true;
|
||||
this.onRun();
|
||||
}
|
||||
|
||||
mutate (mutation, observer) {
|
||||
if (this.isRunning) {
|
||||
this.onMutation(mutation, observer);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfig () {
|
||||
const storedConfig = {};
|
||||
Object.keys(this.config).filter((key) => {
|
||||
return key !== "includes" && key !== "filter";
|
||||
}).forEach((key) => {
|
||||
storedConfig[key] = this.config[key];
|
||||
});
|
||||
localStorage.setItem(this.name + "_config", JSON.stringify(storedConfig));
|
||||
}
|
||||
|
||||
mergeConfig (newConfig) {
|
||||
Object.keys(newConfig).forEach((key) => {
|
||||
this.config[key] = JSON.parse(JSON.stringify(newConfig[key]));
|
||||
});
|
||||
}
|
||||
|
||||
loadConfig () {
|
||||
return new Promise((resolve) => {
|
||||
// TODO: use structuredClone when its more supported
|
||||
this.defaultConfig = JSON.parse(JSON.stringify(this.config));
|
||||
|
||||
const storedConfig = JSON.parse(localStorage.getItem(this.name + "_config"));
|
||||
|
||||
this.onConfigLoad().then((json) => {
|
||||
this.mergeConfig(json);
|
||||
if (storedConfig) {
|
||||
this.mergeConfig(storedConfig);
|
||||
}
|
||||
this.saveConfig();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onReady () {}
|
||||
onCreate () {
|
||||
return new Promise((resolve) => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
onDestroy () {}
|
||||
onRun () {}
|
||||
onMutation (mutation, observer) {}
|
||||
onConfigLoad () {
|
||||
return new Promise((resolve) => {
|
||||
resolve({});
|
||||
});
|
||||
}
|
||||
onSettingInit (key, ul, li) {}
|
||||
|
||||
includeCss (src) {
|
||||
return PleromaModLoader.includeCss(PleromaModLoader.getModDir() + this.name + "/" + src);
|
||||
}
|
||||
|
||||
includeScript (src) {
|
||||
return PleromaModLoader.includeScript(PleromaModLoader.getModDir() + this.name + "/" + src);
|
||||
}
|
||||
|
||||
excludeCss (src) {
|
||||
return PleromaModLoader.excludeCss(PleromaModLoader.getModDir() + this.name + "/" + src);
|
||||
}
|
||||
|
||||
excludeScript (src) {
|
||||
return PleromaModLoader.excludeScript(PleromaModLoader.getModDir() + this.name + "/" + src);
|
||||
}
|
||||
|
||||
fetchJson (src) {
|
||||
console.log("loading " + src);
|
||||
return window.fetch(PleromaModLoader.getModDir() + this.name + "/" + src).then((response) => {
|
||||
return response.json();
|
||||
});
|
||||
}
|
||||
|
||||
api (method, path, params) {
|
||||
return PleromaModLoader.api(method, path, params);
|
||||
}
|
||||
|
||||
enable () {
|
||||
this.ready();
|
||||
localStorage.setItem("pleroma_mod_" + this.name + "_enabled", true);
|
||||
}
|
||||
|
||||
disable () {
|
||||
this.destroy();
|
||||
localStorage.setItem("pleroma_mod_" + this.name + "_enabled", false);
|
||||
}
|
||||
}
|
||||
|
||||
window.__pleromaModLoader = new PleromaModLoader();
|
||||
window.__pleromaModLoader.waitUntilReady();
|
@ -0,0 +1 @@
|
||||
Subproject commit cfd4dd6404d2df6e07e646aff5ff1d606ed48228
|
@ -0,0 +1 @@
|
||||
Subproject commit 5d7ac570770bd7f1d5cba1279c444b53626add3c
|
@ -0,0 +1 @@
|
||||
Subproject commit 440dd5dcb4c97d58726a2a52abbe9c54a8b2f3fb
|
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
TARGET="/opt/pleroma" # CHANGE ME
|
||||
|
||||
yarn install -D
|
||||
|
||||
rm -rf dist/*
|
||||
npm run build
|
||||
|
||||
rsync --update -Pr dist/ "${TARGET}/instance/static/"
|
||||
rsync --update -ra dist/static/ "${TARGET}/instance/static/static"
|
||||
rsync -ra instance/ "${TARGET}/instance/static/instance"
|
||||
|
@ -0,0 +1,108 @@
|
||||
const ChatLayout = {
|
||||
methods: {
|
||||
setChatLayout () {
|
||||
let body = document.querySelector('body')
|
||||
if (body) {
|
||||
body.style.overscrollBehavior = 'none'
|
||||
}
|
||||
if (this.isMobileLayout) {
|
||||
this.setMobileChatLayout()
|
||||
}
|
||||
},
|
||||
unsetChatLayout () {
|
||||
this.unsetMobileChatLayout()
|
||||
let body = document.querySelector('body')
|
||||
if (body) {
|
||||
body.style.overscrollBehavior = 'unset'
|
||||
}
|
||||
},
|
||||
setMobileChatLayout () {
|
||||
// This is a hacky way to adjust the global layout to the mobile chat (without modifying the rest of the app).
|
||||
// This layout prevents empty spaces from being visible at the bottom
|
||||
// of the chat on iOS Safari (`safe-area-inset`) when
|
||||
// - the on-screen keyboard appears and the user starts typing
|
||||
// - the user selects the text inside the input area
|
||||
// - the user selects and deletes the text that is multiple lines long
|
||||
// TODO: unify the chat layout with the global layout.
|
||||
|
||||
let html = document.querySelector('html')
|
||||
if (html) {
|
||||
html.style.overflow = 'hidden'
|
||||
html.style.height = '100%'
|
||||
}
|
||||
|
||||
let body = document.querySelector('body')
|
||||
if (body) {
|
||||
body.style.height = '100%'
|
||||
}
|
||||
|
||||
let app = document.getElementById('app')
|
||||
if (app) {
|
||||
app.style.height = '100%'
|
||||
app.style.overflow = 'hidden'
|
||||
app.style.minHeight = 'auto'
|
||||
}
|
||||
|
||||
let appBgWrapper = window.document.getElementById('app_bg_wrapper')
|
||||
if (appBgWrapper) {
|
||||
appBgWrapper.style.overflow = 'hidden'
|
||||
}
|
||||
|
||||
let main = document.getElementsByClassName('main')[0]
|
||||
if (main) {
|
||||
main.style.overflow = 'hidden'
|
||||
main.style.height = '100%'
|
||||
}
|
||||
|
||||
let content = document.getElementById('content')
|
||||
if (content) {
|
||||
content.style.paddingTop = '0'
|
||||
content.style.height = '100%'
|
||||
content.style.overflow = 'visible'
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.updateSize()
|
||||
})
|
||||
},
|
||||
unsetMobileChatLayout () {
|
||||
let html = document.querySelector('html')
|
||||
if (html) {
|
||||
html.style.overflow = 'visible'
|
||||
html.style.height = 'unset'
|
||||
}
|
||||
|
||||
let body = document.querySelector('body')
|
||||
if (body) {
|
||||
body.style.height = 'unset'
|
||||
}
|
||||
|
||||
let app = document.getElementById('app')
|
||||
if (app) {
|
||||
app.style.height = '100%'
|
||||
app.style.overflow = 'visible'
|
||||
app.style.minHeight = '100vh'
|
||||
}
|
||||
|
||||
let appBgWrapper = document.getElementById('app_bg_wrapper')
|
||||
if (appBgWrapper) {
|
||||
appBgWrapper.style.overflow = 'visible'
|
||||
}
|
||||
|
||||
let main = document.getElementsByClassName('main')[0]
|
||||
if (main) {
|
||||
main.style.overflow = 'visible'
|
||||
main.style.height = 'unset'
|
||||
}
|
||||
|
||||
let content = document.getElementById('content')
|
||||
if (content) {
|
||||
content.style.paddingTop = '60px'
|
||||
content.style.height = 'unset'
|
||||
content.style.overflow = 'unset'
|
||||
}
|
||||
}
|
||||
}
|
||||