Compare commits

...

177 Commits

Author SHA1 Message Date
twl 11d03746eb starting over since merge conflicts are a pain
6 months ago
Not Sam e0cdb2848f
Fix stupidity
8 months ago
Not Sam cb738d9e11
Merge branch 'froth' of git.froth.zone:Sam/pleroma-fe into froth
8 months ago
Not Sam 5fcd6b1957
undo the custom emoji stuff
8 months ago
Not Sam 3b18a8a6e2
Lint
8 months ago
Not Sam 52fea46702
Merge branch 'froth' of git.froth.zone:Sam/pleroma-fe into froth
8 months ago
Absturztaube d237c3cc6d fix loading crash on emoji reacts
8 months ago
Sol Fisher Romanoff 65b13849b9 Add emoji name as title tag
8 months ago
sadposter 0d67481109 fix width
8 months ago
FloatingGhost d2bce51941 resolve merge conflicts
8 months ago
FloatingGhost 07d4433e25 force width
8 months ago
FloatingGhost 66604e987c allow custom reactions
8 months ago
FloatingGhost ca5d0bea60 allow customs
8 months ago
Absturztaube 89a37d84b2 resolve merge conflicts
8 months ago
Not Sam fa64583de2
Fix timeline option, maybe
8 months ago
Not Sam 6e24a983e2
Pull from develop, again
8 months ago
Absturztaube 38158bd561 Merge branch 'develop' into fedi-absturztau-be
9 months ago
Not Sam ee7522671c
Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma-fe into froth
9 months ago
Absturztaube 221aa7e0b4 resolve merge conflicts
9 months ago
Not Sam b51d511983
Add the froth changes back
10 months ago
Not Sam 16ee0077a5
Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma-fe into froth
10 months ago
Absturztaube ef986724ef add dom2component mixin
10 months ago
Absturztaube 5ce9136d89 resolve merge conflicts
10 months ago
Absturztaube 643e087404 resolve merge conflicts
11 months ago
Lynne 1b712bc1a0 Remove ruffle
1 year ago
Absturztaube 12db1d8719 Merge branch 'develop' into fedi-absturztau-be
1 year ago
Absturztaube b4b906689f add threading
1 year ago
Absturztaube d34cef391b resolve merge confilcts
1 year ago
Tusooa Zhu fe0e7bd63c
Fix timeline jump when scrolling
1 year ago
Tusooa Zhu 78f573af47
Make replying and mediaPlaying controlled
1 year ago
Tusooa Zhu 12ed9a1799
Fix virtual scrolling for tree threading
1 year ago
Tusooa Zhu 0b576b64e2
Clean up debug code for tree threading
1 year ago
Tusooa Zhu 708633d6b1
Fix controlled status display toggles
1 year ago
Tusooa Zhu 59a2f65a33
Add English translations for other replies count
1 year ago
Tusooa Zhu c069a9f799
Add other replies count for reply list link
1 year ago
Tusooa Zhu c634e15305
Do not display replies inside status as link if there are no other replies
1 year ago
Tusooa Zhu a1404f7735
Add English translation for position of other replies button pref
1 year ago
Tusooa Zhu 70ec3ad09e
Make position of other replies button a pref
1 year ago
Tusooa Zhu 8a4c0bfa18
Add English translation for show all conversation button improvement
1 year ago
Tusooa Zhu 00cc721344
Improve "show full conversation" interaction
1 year ago
Tusooa Zhu a917bdc34b
Make other replies button stretch along the row
1 year ago
Tusooa Zhu 4648bc6f72
Optimise thread ancestor borders
1 year ago
Tusooa Zhu 5643314922
Optimise thread ancestor display style
1 year ago
Tusooa Zhu 89761743b8
Reset thread open state when collapsed
1 year ago
Tusooa Zhu e01445b1d9
Clean up
1 year ago
Tusooa Zhu 5a37ea5a8e
Highlight ancestor of the current status when diving back to top
1 year ago
Tusooa Zhu 1fdba77ae5
Add English translation for Misskey-style tree view
1 year ago
Tusooa Zhu 7dd5e0fc8e
Implement Misskey-style tree view
1 year ago
Tusooa Zhu 38a67cc2e2
Remove horizontal border and thicken vertical border in a thread tree
1 year ago
Tusooa Zhu 2c91a020bc
Make dive/undive button clickable along the whole row
1 year ago
Tusooa Zhu 2a6f0c4a34
Optimize thread border radius
1 year ago
Tusooa Zhu f8d25d2c2a
Optimize thread display
1 year ago
Tusooa Zhu b7e179c1fe
Fix the bug where toggleShowingTall does not work
1 year ago
Tusooa Zhu 46feecee70
Fix status undefined in parentOf
1 year ago
Tusooa Zhu 9029344e1f
Add English translations for max depth in thread
1 year ago
Tusooa Zhu 891fb00107
Add settings for max depth in thread
1 year ago
Tusooa Zhu 640d3041ef
Use mergedConfig properly
1 year ago
Tusooa Zhu 28469988dd
Fallback to simpleTree style
1 year ago
Tusooa Zhu ac464be063
Undive when collapsed
1 year ago
Tusooa Zhu c221805695
Clean up
1 year ago
Tusooa Zhu 49398566d3
Lint
1 year ago
Tusooa Zhu 9ccc374feb
Add English translation for simple tree
1 year ago
Tusooa Zhu ad5c0abe14
Add simple tree style navigation
1 year ago
Tusooa Zhu ff59c5a785
Add English translation for diving
1 year ago
Tusooa Zhu 93bcee9516
Add dive functionality
1 year ago
Tusooa Zhu f0c717ce5f
Add English translations for diving
1 year ago
Tusooa Zhu 4f775b6be4
Support diving into one status in a conversation
1 year ago
Tusooa Zhu 436597a906
Make status display controlled
1 year ago
Tusooa Zhu e6120df550
Add English translations for message threading
1 year ago
Tusooa Zhu a4a0858110
Make show full thread message account for numbers
1 year ago
Tusooa Zhu b1f4b1bff3
Implement thread folding/expanding
1 year ago
Tusooa Zhu 814a27749a
Add tree-style thread display
1 year ago
Absturztaube a0cf440fac swap of react and fav
2 years ago
Absturztaube d5e091e9af update readme
2 years ago
Absturztaube 5a5320b71c Merge branch 'tusooa/pleroma-fe-from/develop/tusooa/media-touch-actions' into fedi-absturztau-be
2 years ago
Absturztaube 7fe7339ea7 resolve merge conflicts
2 years ago
Tusooa Zhu 3b6b8b96c4
Bump pinch-zoom-element version
2 years ago
Tusooa Zhu 4c2a7aabe5
Clean up
2 years ago
Tusooa Zhu 3366c915e9
Check whether we swiped only for mouse pointer
2 years ago
Tusooa Zhu db71bbf358
Scale swipe threshold with viewport width
2 years ago
Tusooa Zhu 7b77c0c884
Update pinch-zoom-element
2 years ago
Tusooa Zhu 1478e72fcc
Allow pinch-zoom to fill the whole screen
2 years ago
Tusooa Zhu 33384af5df
Use native click for hiding overlay
2 years ago
Tusooa Zhu 9d4dd64276
Reset position on swipe end even if we cannot navigate
2 years ago
Tusooa Zhu e2f3929872
Make lint happy
2 years ago
Tusooa Zhu 4552c28e06
Prevent the click event from firing on content below modal
2 years ago
Tusooa Zhu 214338b9f0
Add missing swipe click component
2 years ago
Tusooa Zhu cd9384adae
Clean up
2 years ago
Tusooa Zhu 7469849c39
Add swipe-click handler to media modal
2 years ago
Tusooa Zhu 0a63208da7
Use pinch-zoom-element for pinch zoom functionality
2 years ago
Tusooa Zhu 0421c06d47
Add pan threshold
2 years ago
Tusooa Zhu 7d767f840b
Handle pinch action
2 years ago
Tusooa Zhu aa70c31950
Preview swipe action
2 years ago
Tusooa Zhu 61509d1b1e
Make media modal be aware of multi-touch actions
2 years ago
Absturztaube 2b6974dcad fix chats
2 years ago
Absturztaube 6594cdaa63 remove sorting because performance
2 years ago
Absturztaube b5cc8ec3ae update readme
2 years ago
Absturztaube 0fc86d5bfe add tags as buttons to posts
2 years ago
Absturztaube 77f8537f61 improved sidebar ordering when 3rd column is active
2 years ago
Absturztaube 240bce92cd Merge branch 'fix-themes-select' into fedi-absturztau-be
2 years ago
Absturztaube 9be1cc34ba temporary fix for external links
2 years ago
Absturztaube 3336572a74 remove order style when sidebarAlign is active
2 years ago
Absturztaube fcf1c7b4b4 resolve merge conflicts
2 years ago
Absturztaube c8e517828e Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube c44f2bbcd6 Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube 6064e31c5d Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube 97113bc5df minor fix to sub menu in nav panel
2 years ago
Absturztaube 7f05730e9b resolve merge conflicts and update fixes
2 years ago
Absturztaube 6ef591bdcc Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube 6e43a7d23c update readme
2 years ago
Absturztaube 862a5a86e7 compact user panel
2 years ago
Absturztaube f304fed1e9 added compact nav panel
2 years ago
Absturztaube 5ef3133f75 fix move notification column checkbox
2 years ago
Absturztaube 0cfd263ef4 Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube 94c96345e1 fix language stuff
2 years ago
Absturztaube ba808076ca resolve merge conflicts
2 years ago
Absturztaube eaaa64dde8 ble
2 years ago
Absturztaube 6b6558d924 add changes in readme
2 years ago
Absturztaube ecd5d78bc2 add zero width space when padding of emojis is disabled
2 years ago
Absturztaube a85c1d562c resolve merge conflicts
2 years ago
Absturztaube 2a71d425cd change repo paths
2 years ago
Absturztaube 381c4e7f82 resolve merge conflicts
2 years ago
Absturztaube 026dc263e5 Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube e15095d0dd Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube ad728d9046 resolve conflichts
2 years ago
Absturztaube a6822d26bb Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube 8065afc4d7 resolve merge conflicts
2 years ago
Absturztaube a43623c5a5 Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube 7a9bd70a09 Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube 575ce2c65e Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube 07853ed322 Merge branch 'develop' into fedi-absturztau-be
2 years ago
Absturztaube aabd393e15 add settings for third column
3 years ago
Absturztaube 1e65016d71 fix flex
3 years ago
Absturztaube 2478d8b04e change width
3 years ago
Absturztaube 2e2a261e3d move features panel to the right
3 years ago
Absturztaube ee67b579c5 add 3rd column for testing
3 years ago
Absturztaube 6a77b27a42 resolve merge conflicts
3 years ago
Absturztaube e77cd1d625 fix pleroma-mod-loader ref
3 years ago
Absturztaube f2f11f7f63 add to language switcher
3 years ago
Absturztaube 7668321c98 add en nyan
3 years ago
Absturztaube 2cd6d336ba remove dublicate
3 years ago
Absturztaube ee45f689ac remove dublicate add mod loader
3 years ago
Absturztaube 7b0425c985 Merge branch 'direct-conversations' into fedi-absturztau-be
3 years ago
Absturztaube 7fa2dfecc6 Merge branch 'direct-conversations' of https://git.pleroma.social/eugenijm/pleroma-fe into direct-conversations
3 years ago
eugenijm 0d7d8e9f33 Submit on enter fixes
3 years ago
eugenijm f2b3d1e6b0 Use streaming for real time updates instead of notifications, disable
3 years ago
eugenijm 6c2c0883ce Use since_id when pulling the current chat messages
3 years ago
eugenijm fdef990c6a Submit on enter, start a new line on shift+enter
3 years ago
eugenijm 5fc9ef0bfb WIP chat fixes
3 years ago
eugenijm b05a86b280 WIP keep the on screen keyboard after a message send.
3 years ago
eugenijm 5996954c4a Reset the chat list on logout
3 years ago
eugenijm c82436cd8a WIP Chat refactoring
3 years ago
eugenijm 93049e9d52 WIP preserve scroll position during posting form resize, attachment upload, window resize, disable auto-focus for mobile
3 years ago
eugenijm 5f7494f134 Chat header alignment fixes for the mobile layout
3 years ago
eugenijm c1faeacee8 Set file limit in the chat posting form
3 years ago
eugenijm 6b272b9c99 WIP chat improvements
3 years ago
eugenijm 3dbe0d1e61 WIP display updated_at in the chat list, use updated_at to keep the chat list sorted
3 years ago
eugenijm cf4d3ee1bf WIP display attachment type in the last message
3 years ago
eugenijm c9870a9d43 WIP keep last_message updated
3 years ago
eugenijm 09da927def WIP chat refactoring
3 years ago
eugenijm 99de78b80e WIP chat
3 years ago
eugenijm d2456d5fea Chat message deletion
3 years ago
eugenijm 855f36eeda wip
3 years ago
eugenijm 1b51b02483 WIP chat fixes
3 years ago
eugenijm 6c487f0c58 WIP attachments
3 years ago
eugenijm fc3d7a7565 WIP: add custom emoji
3 years ago
eugenijm 8a8a9ad562 WIP notification count
3 years ago
eugenijm d48b7a7d58 WIP chat
3 years ago
eugenijm 5fdb5c554d WIP load chat messages on scroll up
3 years ago
eugenijm 86cc4ce08d WIP attachments
3 years ago
eugenijm c273560408 WIP display the last message in the chat list
3 years ago
eugenijm 0f3c667eb8 wip
3 years ago
eugenijm bd5b3e8922 wip
3 years ago
eugenijm aa1f2a1c3f wip
3 years ago
eugenijm 5e93ca3edb WIP chat avatars
3 years ago
eugenijm f06ec18cd7 Chat fixes
3 years ago
eugenijm 804cf3abc5 WIP: Chats
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

9
.gitmodules vendored

@ -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

@ -4,6 +4,19 @@
![screenshot](/uploads/796c5ecf985ed1e2b0943ee0df131ed0/DJVqSJ0.png)
# Changes in this Fork
* script tag in index.html for [pleroma-mod-loader](https://git.pleroma.social/absturztaube/pleroma-mod-loader)
* ability to move notifications to a seperate column
* insert zero width space when padding of emojis is disabled
* add custom language "English (Nyan)"
* pointing version links to my gitlab repos
* optional compact styles provided by craftplacer
* tags as buttons bellow a post
* [pinch and pan media](https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1403)
* swap of react and favorite button in status
* adding __vueComponent__ to DOM nodes to make new mods work
# For Translators
To translate Pleroma-FE, add your language to [src/i18n/messages.js](https://git.pleroma.social/pleroma/pleroma-fe/blob/develop/src/i18n/messages.js). Pleroma-FE will set your language by your browser locale, but you can temporarily force it in the code by changing the locale in main.js.

@ -21,7 +21,6 @@ var compiler = webpack(webpackConfig)
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
writeToDisk: true,
stats: {
colors: true,
chunks: false

@ -3,8 +3,7 @@ var config = require('../config')
var utils = require('./utils')
var projectRoot = path.resolve(__dirname, '../')
var ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin')
var CopyPlugin = require('copy-webpack-plugin');
var { VueLoaderPlugin } = require('vue-loader')
var { VueLoaderPlugin } = require("vue-loader");
var env = process.env.NODE_ENV
// check env & config/index.js to decide weither to enable CSS Sourcemaps for the
@ -115,19 +114,6 @@ module.exports = {
entry: path.join(__dirname, '..', 'src/sw.js'),
filename: 'sw-pleroma.js'
}),
new VueLoaderPlugin(),
// This copies Ruffle's WASM to a directory so that JS side can access it
new CopyPlugin({
patterns: [
{
from: "node_modules/ruffle-mirror/*",
to: "static/ruffle",
flatten: true
},
],
options: {
concurrency: 100,
},
})
new VueLoaderPlugin()
]
}

@ -10,5 +10,6 @@
<noscript>To use Pleroma, please enable JavaScript.</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script type="text/javascript" src="/instance/pleroma-mod-loader.js"></script>
</body>
</html>

Binary file not shown.

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?&amp;type=playlist&amp;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"

@ -15,8 +15,12 @@
class="app-layout container"
:class="classes"
>
<div class="underlay"/>
<div id="sidebar" class="column -scrollable" :class="{ '-show-scrollbar': showScrollbars }">
<div class="underlay" />
<div
id="sidebar"
class="column -scrollable"
:class="{ '-show-scrollbar': showScrollbars }"
>
<user-panel />
<template v-if="layoutType !== 'mobile'">
<nav-panel />
@ -26,7 +30,11 @@
<div id="notifs-sidebar" />
</template>
</div>
<div id="main-scroller" class="column main" :class="{ '-full-height': isChats }">
<div
id="main-scroller"
class="column main"
:class="{ '-full-height': isChats }"
>
<div
v-if="!currentUser"
class="login-hint panel panel-default"
@ -40,7 +48,11 @@
</div>
<router-view />
</div>
<div id="notifs-column" class="column -scrollable" :class="{ '-show-scrollbar': showScrollbars }"/>
<div
id="notifs-column"
class="column -scrollable"
:class="{ '-show-scrollbar': showScrollbars }"
/>
</div>
<media-modal />
<shout-panel

@ -15,6 +15,8 @@ import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
import { applyTheme } from '../services/style_setter/style_setter.js'
import FaviconService from '../services/favicon_service/favicon_service.js'
import DomNodeToComponent from '../modules/domNodeToComponent.js'
let staticInitialResults = null
const parsedInitialResults = () => {
@ -392,6 +394,7 @@ const afterStoreSetup = async ({ store, i18n }) => {
app.use(vClickOutside)
app.use(VBodyScrollLock)
app.use(DomNodeToComponent)
app.component('FAIcon', FontAwesomeIcon)
app.component('FALayers', FontAwesomeLayers)

@ -1,5 +1,4 @@
import StillImage from '../still-image/still-image.vue'
import Flash from '../flash/flash.vue'
import VideoAttachment from '../video_attachment/video_attachment.vue'
import nsfwImage from '../../assets/nsfw.png'
import fileTypeService from '../../services/file_type/file_type.service.js'
@ -61,7 +60,6 @@ const Attachment = {
}
},
components: {
Flash,
StillImage,
VideoAttachment
},

@ -227,21 +227,6 @@
<!-- eslint-enable vue/no-v-html -->
</div>
</div>
<span
v-if="type === 'flash' && !hidden"
class="flash-container"
:href="attachment.url"
@click.stop.prevent="openModal"
>
<Flash
ref="flash"
class="flash"
:src="attachment.large_thumb_url || attachment.url"
@playerOpened="setFlashLoaded(true)"
@playerClosed="setFlashLoaded(false)"
/>
</span>
</div>
<div
v-if="size !== 'hide' && !hideDescription && (edit || (localDescription && showDescription))"

@ -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'
}
}
}