♻️ Cleaned up
Signed-off-by: milky <op@gfy.lol>
This commit is contained in:
commit
9a4639194e
22
LICENSE
Normal file
22
LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Milky
|
||||
Copyright (c) 2021 TaiAurori
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
14
README.md
Normal file
14
README.md
Normal file
@ -0,0 +1,14 @@
|
||||
# powercord-redirects
|
||||
🔎 Privacy-orientated plugin
|
||||
|
||||
## Why?
|
||||
|
||||
This was forked due to the hardcoded initial values being outdated and offline. This might be something that'll end up maintained, with my own self-hosted alternatives.
|
||||
|
||||
## Supported services
|
||||
- Youtube -> [yewtu.be](https://yewtu.be)
|
||||
- Twitter -> [nitter.net](https://nitter.net)
|
||||
- Reddit -> [libreddit.spike.codes](https://libreddit.spike.codes)
|
||||
- Instagram -> [bibliogram.pussthecat.org](https://bibliogram.pussthecat.org)
|
||||
- Wikipedia -> [wikiless.org](https://wikiless.org)
|
||||
- Medium -> [scribe.rip](https://scribe.rip)
|
68
Settings.jsx
Normal file
68
Settings.jsx
Normal file
@ -0,0 +1,68 @@
|
||||
var settings;
|
||||
|
||||
const { React, getModuleByDisplayName } = require("powercord/webpack");
|
||||
const { Category, TextInput, SwitchItem } = require("powercord/components/settings");
|
||||
const FormText = getModuleByDisplayName("FormText", false);
|
||||
|
||||
const services = require("./services.js")
|
||||
|
||||
module.exports = class Settings extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {}
|
||||
settings = this.props;
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<br />
|
||||
<br />
|
||||
<div>
|
||||
{services.map(s => {
|
||||
return (
|
||||
<Category
|
||||
name={s.name + " (" + s.replaces + ")"}
|
||||
opened={this.state["opened_" + s.name]}
|
||||
onChange={() => {
|
||||
this.setState({ ["opened_" + s.name]: !this.state["opened_" + s.name] });
|
||||
}}>
|
||||
<SwitchItem
|
||||
note={<span>Toggles whether {s.replaces} embeds will be replaced with {s.name}.</span>}
|
||||
value={settings.getSetting(s.name.toLowerCase() + "Active", true)}
|
||||
onChange={() => {
|
||||
settings.toggleSetting(s.name.toLowerCase() + "Active", true);
|
||||
}}
|
||||
>
|
||||
Replace Embeds
|
||||
</SwitchItem>
|
||||
<SwitchItem
|
||||
note={<span>Toggles whether {s.replaces} links will be replaced with {s.name}.</span>}
|
||||
value={settings.getSetting(s.name.toLowerCase() + "LinkActive", true)}
|
||||
onChange={() => {
|
||||
settings.toggleSetting(s.name.toLowerCase() + "LinkActive", true);
|
||||
}}
|
||||
>
|
||||
Replace Links
|
||||
</SwitchItem>
|
||||
<TextInput
|
||||
note={
|
||||
<span>
|
||||
{settings.getSetting(s.name.toLowerCase() + "Instance", s.default) == s.replacedURL
|
||||
? <FormText style={{ color: "#ff6666" }}>You think you're real funny, don't you?</FormText>
|
||||
: ""}This is the {s.name} instance that will replace all {s.replaces} links/embeds.
|
||||
</span>
|
||||
}
|
||||
defaultValue={settings.getSetting(s.name.toLowerCase() + "Instance", s.default)}
|
||||
onChange={(val) => settings.updateSetting(s.name.toLowerCase() + "Instance", val)}
|
||||
>
|
||||
{s.name} Instance
|
||||
</TextInput>
|
||||
</Category >
|
||||
)
|
||||
})}
|
||||
</div >
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
135
index.js
Normal file
135
index.js
Normal file
@ -0,0 +1,135 @@
|
||||
/* Copyright (C) 2020 TaiAurori (Gabriel Sylvain) - All Rights Reserved
|
||||
* You may use, distribute and modify this code under the
|
||||
* terms of the MIT license.
|
||||
* Basically, you can change and redistribute this code
|
||||
* but this copyright notice must remain unmodified.
|
||||
*/
|
||||
|
||||
let settings;
|
||||
|
||||
const { Plugin } = require("powercord/entities");
|
||||
const { inject, uninject } = require("powercord/injector");
|
||||
const { getModule, React } = require("powercord/webpack");
|
||||
const { findInReactTree } = require("powercord/util");
|
||||
const { clipboard } = getModule(["clipboard"], false) || {};
|
||||
|
||||
const Settings = require("./Settings");
|
||||
|
||||
const services = require("./services.js");
|
||||
|
||||
const redirectLinkColor = "#0091ff"
|
||||
|
||||
module.exports = class EmbedRedirect extends Plugin {
|
||||
startPlugin() {
|
||||
settings = this.settings;
|
||||
powercord.api.settings.registerSettings(this.entityID, {
|
||||
category: this.entityID,
|
||||
label: this.manifest.name,
|
||||
render: Settings
|
||||
});
|
||||
this.initInject();
|
||||
}
|
||||
|
||||
trimLink(link) {
|
||||
let trimmed = link
|
||||
if (trimmed.startsWith("https://") || trimmed.startsWith("http://")) trimmed = trimmed.split("://")[1]
|
||||
if (trimmed.endsWith("/")) trimmed = trimmed.slice(0, trimmed.length - 1)
|
||||
if (trimmed.includes("/")) trimmed = trimmed.split("/")[0]
|
||||
trimmed = trimmed.trim() // trimmed x1000
|
||||
return trimmed
|
||||
}
|
||||
|
||||
async initInject() {
|
||||
inject("embed-redirect", (await getModule(["MessageAccessories"])), "default", (args, res) => {
|
||||
res.props.message.embeds = res.props.message.embeds.map((embed) => {
|
||||
services.forEach((s) => {
|
||||
if (settings.get(s.name.toLowerCase() + "Active", true)) {
|
||||
if (s.embedMatches(embed)) {
|
||||
s.replaceEmbed(embed, settings)
|
||||
}
|
||||
}
|
||||
})
|
||||
return embed
|
||||
})
|
||||
return res;
|
||||
})
|
||||
|
||||
let Anchor = await getModule(m => m.default?.displayName === "Anchor")
|
||||
inject("embed-redirect-link", Anchor, "default", (args, res) => {
|
||||
if (res.props.href) {
|
||||
let trimmed = this.trimLink(res.props.href)
|
||||
if (trimmed in services.guide) {
|
||||
let service = services[services.guide[trimmed]]
|
||||
if (service) {
|
||||
if (settings.get(service.name.toLowerCase() + "LinkActive", true)) {
|
||||
service.replaceLink(res, settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
})
|
||||
Anchor.default.displayName = "Anchor"
|
||||
|
||||
inject("embed-redirect-textbox-link", (await getModule(m => m.default?.displayName === "SlateChannelTextArea")).default.prototype, "render", (args, res) => {
|
||||
if (settings.get("enableCosmetics", true)) {
|
||||
setTimeout(() => { // yes this is a dumb workaround, no i dont care
|
||||
let inputItems = res.props.children[1].ref.current.children[0]?.children[0]?.children[0]?.children
|
||||
if (inputItems) {
|
||||
for (let item in inputItems) {
|
||||
if (!isNaN(new Number(item).valueOf())) {
|
||||
if (inputItems[item].children[0].className.includes("fakeLink")) {
|
||||
let trimmed = this.trimLink(inputItems[item].children[0].children[0].innerText)
|
||||
if (trimmed in services.guide) {
|
||||
let service = services[services.guide[trimmed]]
|
||||
if (service) {
|
||||
if (settings.get(service.name.toLowerCase() + "LinkActive", true)) {
|
||||
inputItems[item].children[0].children[0].style.color = redirectLinkColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0)
|
||||
}
|
||||
return res
|
||||
})
|
||||
|
||||
const Menu = await getModule(['MenuGroup', 'MenuItem'])
|
||||
const MessageContextMenu = await getModule(m => m.default && m.default.displayName == 'MessageContextMenu')
|
||||
inject('embed-redirect-context-menu', MessageContextMenu, 'default', (args, res) => {
|
||||
if (args[0].target.tagName.toLowerCase() == "a" && args[0].target.getAttribute("originallink")) {
|
||||
if (!findInReactTree(res, e => e.props && e.props.id == 'copy-redirected-link')) {
|
||||
let copyLink = findInReactTree(res, e => e.props && e.props.id == 'copy-native-link');
|
||||
let openLink = findInReactTree(res, e => e.props && e.props.id == 'open-native-link');
|
||||
let copyLinkGroup = findInReactTree(res, e => e.props && e.props.children && e.props.children[0] && e.props.children[0].props && e.props.children[0].props.id == 'copy-native-link');
|
||||
if (copyLink) {
|
||||
(copyLinkGroup ? copyLinkGroup : res).props.children.splice((copyLinkGroup ? 1 : 2), 0,
|
||||
React.createElement(Menu.MenuItem,
|
||||
{
|
||||
action: () => { clipboard.copy(args[0].target.getAttribute("href")) },
|
||||
id: 'copy-redirected-link',
|
||||
label: 'Copy Redirected Link'
|
||||
}
|
||||
)
|
||||
)
|
||||
copyLink.props.action = () => { clipboard.copy(args[0].target.getAttribute("originallink")) }
|
||||
openLink.props.action = () => { window.open(args[0].target.getAttribute("originallink")) }
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
})
|
||||
MessageContextMenu.default.displayName = 'MessageContextMenu'
|
||||
}
|
||||
|
||||
pluginWillUnload() {
|
||||
powercord.api.settings.unregisterSettings(this.entityID);
|
||||
uninject("embed-redirect");
|
||||
uninject("embed-redirect-link");
|
||||
uninject("embed-redirect-context-menu");
|
||||
uninject("embed-redirect-textbox-link");
|
||||
};
|
||||
};
|
10
manifest.json
Normal file
10
manifest.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "Embed Redirect",
|
||||
"version": "1.0.0",
|
||||
"description": "Changes the destination of embeds for some track-happy services.",
|
||||
"author": "TaiAurori#6781",
|
||||
"license": "MIT",
|
||||
"optionalDependencies": [
|
||||
"mtega"
|
||||
]
|
||||
}
|
175
services.js
Normal file
175
services.js
Normal file
@ -0,0 +1,175 @@
|
||||
const { React } = require("powercord/webpack")
|
||||
|
||||
const redirectLinkColor = "#0091ff"
|
||||
|
||||
function setting(settings, one, two) {
|
||||
let instance = settings.get(one, two)
|
||||
if (instance.startsWith("https://") || instance.startsWith("http://")) instance = instance.split("://")[1]
|
||||
if (instance.endsWith("/")) instance = instance.slice(0, instance.length - 1)
|
||||
return instance
|
||||
}
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
name: "Invidious",
|
||||
replaces: "YouTube",
|
||||
instances: "https://github.com/iv-org/documentation/blob/master/Invidious-Instances.md",
|
||||
default: "yewtu.be",
|
||||
replacedURL: "youtube.com",
|
||||
embedMatches: (embed) => { return embed.video && (embed.video.originalURL ? embed.video.originalURL : embed.video.url).includes("youtube") },
|
||||
replaceEmbed: (embed, settings) => {
|
||||
if (!embed.video.originalURL) embed.video.originalURL = embed.video.url;
|
||||
let instance = setting(settings, "invidiousInstance", "yewtu.be")
|
||||
if (!instance) {
|
||||
embed.video.url = "data:text/plain,No Invidious instance selected. You can either:\n- Go to the settings page for Embed Redirect and select one\n- Turn off Embed Redirect\n\n\n"
|
||||
} else {
|
||||
if (!settings.get("redirectColorEmbeds", true)) {
|
||||
embed.provider.url = "https://" + instance
|
||||
embed.author.url = embed.author.url.replace("www.", "").replace("youtube.com", instance)
|
||||
embed.url = embed.url.replace("www.", "").replace("youtube.com", instance)
|
||||
}
|
||||
embed.video.url = embed.video.url.replace("www.", "").replace("youtube.com", instance)
|
||||
if (settings.get("enableCosmetics", true)) {
|
||||
embed.provider.name = "Invidious 🠔 YouTube"
|
||||
embed.color = "#0091ff"
|
||||
}
|
||||
}
|
||||
},
|
||||
replaceLink: (link, settings) => {
|
||||
if (!link.props.originallink) link.props.originallink = link.props.href
|
||||
link.props.href = link.props.href.replace(/(www\.)?youtube\.com|youtu\.be/, setting(settings, "invidiousInstance", "invidious.kavin.rocks"))
|
||||
link.props.onClick = (e) => { }
|
||||
if (settings.get("enableCosmetics", true)) link.props.style = { color: redirectLinkColor }
|
||||
link.props.title = link.props.href
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Nitter",
|
||||
replaces: "Twitter",
|
||||
instances: "https://github.com/zedeus/nitter/wiki/Instances",
|
||||
default: "nitter.net",
|
||||
replacedURL: "twitter.com",
|
||||
embedMatches: (embed) => { return embed.footer && embed.footer.text == "Twitter" },
|
||||
replaceEmbed: (embed, settings) => {
|
||||
let instance = setting(settings, "nitterInstance", "nitter.net")
|
||||
if (instance) {
|
||||
if (!settings.get("redirectColorEmbeds", true)) {
|
||||
embed.url = embed.url.replace("twitter.com", instance)
|
||||
embed.author.url = embed.author.url.replace("twitter.com", instance)
|
||||
}
|
||||
if (embed.mtega) embed.video.url = embed.video.url.replace("twitter.com", instance)
|
||||
if (settings.get("enableCosmetics", true)) {
|
||||
embed.footer.text = "Nitter 🠔 Twitter"
|
||||
delete embed.footer.iconProxyURL
|
||||
delete embed.footer.iconURL
|
||||
embed.color = "#0091ff"
|
||||
}
|
||||
}
|
||||
},
|
||||
replaceLink: (link, settings) => {
|
||||
if (!link.props.originallink) link.props.originallink = link.props.href
|
||||
link.props.href = link.props.href.replace(link.props.href.includes("fxtwitter.com") ? "fxtwitter.com" : "twitter.com", setting(settings, "nitterInstance", "nitter.moomoo.me"))
|
||||
link.props.onClick = (e) => { }
|
||||
if (settings.get("enableCosmetics", true)) link.props.style = { color: redirectLinkColor }
|
||||
link.props.title = link.props.href
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Libreddit",
|
||||
replaces: "reddit",
|
||||
instances: "https://github.com/spikecodes/libreddit#instances",
|
||||
default: "libreddit.spike.codes",
|
||||
replacedURL: "reddit.com",
|
||||
embedMatches: (embed) => { return embed.provider && embed.provider.name == "reddit" },
|
||||
replaceEmbed: (embed, settings) => {
|
||||
let instance = setting(settings, "libredditInstance", "libreddit.spike.codes")
|
||||
if (instance) {
|
||||
if (!settings.get("redirectColorEmbeds", true)) embed.url = embed.url.replace("reddit.com", instance)
|
||||
if (settings.get("enableCosmetics", true)) {
|
||||
embed.provider.name = "Libreddit 🠔 reddit"
|
||||
embed.color = "#0091ff"
|
||||
}
|
||||
}
|
||||
},
|
||||
replaceLink: (link, settings) => {
|
||||
if (!link.props.originallink) link.props.originallink = link.props.href
|
||||
link.props.href = link.props.href.replace(/((old|new|www)\.)?reddit\.com|redd\.it/, setting(settings, "libredditInstance", "libreddit.silkky.cloud"))
|
||||
link.props.onClick = (e) => { }
|
||||
if (settings.get("enableCosmetics", true)) link.props.style = { color: redirectLinkColor }
|
||||
link.props.title = link.props.href
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Bibliogram",
|
||||
replaces: "Instagram",
|
||||
instances: "https://git.sr.ht/~cadence/bibliogram-docs/tree/master/docs/Instances.md",
|
||||
default: "bibliogram.pussthecat.org",
|
||||
replacedURL: "instagram.com",
|
||||
embedMatches: (embed) => { return false },
|
||||
replaceEmbed: (embed, settings) => { },
|
||||
replaceLink: (link, settings) => {
|
||||
if (!link.props.originallink) link.props.originallink = link.props.href
|
||||
let subpage = link.props.href.split("://")[1].split("/")[1]
|
||||
if (!(["", "p", "about"].includes(subpage))) {
|
||||
link.props.href = link.props.href.replace("www.instagram", "instagram").replace("instagram.com/", "instagram.com/u/")
|
||||
}
|
||||
link.props.href = link.props.href.replace("www.instagram", "instagram").replace("instagram.com", setting(settings, "bibliogramInstance", "bibliogram.pussthecat.org"))
|
||||
link.props.onClick = (e) => { }
|
||||
if (settings.get("enableCosmetics", true)) link.props.style = { color: redirectLinkColor }
|
||||
link.props.title = link.props.href
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Wikiless",
|
||||
replaces: "Wikipedia",
|
||||
instances: "https://codeberg.org/orenom/Wikiless#instances",
|
||||
default: "wikiless.org",
|
||||
replacedURL: "en.wikipedia.org",
|
||||
embedMatches: (embed) => { return false },
|
||||
replaceEmbed: (embed, settings) => { },
|
||||
replaceLink: (link, settings) => {
|
||||
if (!link.props.originallink) link.props.originallink = link.props.href
|
||||
link.props.href = link.props.href.replace("en.wikipedia.org", setting(settings, "wikilessInstance", "wikiless.org"))
|
||||
link.props.onClick = (e) => { }
|
||||
if (settings.get("enableCosmetics", true)) link.props.style = { color: redirectLinkColor }
|
||||
link.props.title = link.props.href
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Scribe",
|
||||
replaces: "Medium",
|
||||
instances: null,
|
||||
default: "scribe.rip",
|
||||
replacedURL: "medium.com",
|
||||
embedMatches: (embed) => { return embed.provider && embed.provider.name == "Medium" },
|
||||
replaceEmbed: (embed, settings) => {
|
||||
if (settings.get("enableCosmetics", true)) {
|
||||
embed.provider.name = "Scribe 🠔 Medium"
|
||||
}
|
||||
},
|
||||
replaceLink: (link, settings) => {
|
||||
if (!link.props.originallink) link.props.originallink = link.props.href
|
||||
link.props.href = link.props.href.replace("medium.com", setting(settings, "scribeInstance", "scribe.rip"))
|
||||
link.props.onClick = (e) => { }
|
||||
if (settings.get("enableCosmetics", true)) link.props.style = { color: redirectLinkColor }
|
||||
link.props.title = link.props.href
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
module.exports.guide = {
|
||||
"www.youtube.com": 0,
|
||||
"youtube.com": 0,
|
||||
"youtu.be": 0,
|
||||
"twitter.com": 1,
|
||||
"fxtwitter.com": 1,
|
||||
"www.reddit.com": 2,
|
||||
"old.reddit.com": 2,
|
||||
"new.reddit.com": 2,
|
||||
"reddit.com": 2,
|
||||
"redd.it": 2,
|
||||
"instagram.com": 3,
|
||||
"www.instagram.com": 3,
|
||||
"en.wikipedia.org": 4,
|
||||
"medium.com": 5,
|
||||
}
|
Loading…
Reference in New Issue
Block a user