Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
BetterDiscord-Animated-Status-master/.github/ISSUE_TEMPLATE/i-need-help.md
---
name: I need help
about: There is an issue with the plugin / I don't know how to do something
title: "[Help] ..."
labels: help wanted
assignees: toluschr
---
<!--
Did you read README.md?
I can't help you, if you don't provide a clear explanation of the problem you're facing.
A good example would be:
I am using the newest Discord version and installed the newest version of the plugin.
When opening the settings page and setting a custom status, clicking the save button
does not apply the status. There is no error message. Closing and reopening the settings page shows the changes. Restarting discord fixes the problem temporarily.
When opening a new issue, please _respond_ after there was an effort to help you.
-->
BetterDiscord-Animated-Status-master/LICENSE
Copyright 2019-2021 The Contributors
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.
BetterDiscord-Animated-Status-master/ReadMe.md
# BetterDiscord-Animated-Status
<!-- vim-markdown-toc GFM -->
* [Installation](#installation)
* [Usage](#usage)
* [Timeout / Time Per Keyframe](#timeout--time-per-keyframe)
* ['rich' vs 'raw' editor](#rich-vs-raw-editor)
* [Animations](#animations)
* [Examples](#examples)
* [Discord Nitro Emoji](#discord-nitro-emoji)
* [Custom Javascript](#custom-javascript)
<!-- vim-markdown-toc -->
## Installation
Install [BetterDiscord](https://github.com/rauenzi/BetterDiscordApp)\
Download [animated-status.plugin.js](/animated-status.plugin.js?raw=true) into the following directory\
Mac: `~/Library/Preferences/BetterDiscord`\
Windows: `%appdata%\BetterDiscord\plugins`\
Linux: `~/.config/BetterDiscord/plugins`
## Usage
Open Discord, go to Settings\>Plugins, enable AnimatedStatus and click on Settings.\
Enter the required information into the input fields and click `save`
## Timeout / Time Per Keyframe
The value specifies the length of each animation step in milliseconds.
Example: With a timeout of 2000, the following animation would take 4 seconds to complete
```
"abc"
"def"
```
To prevent the discord server from being spammed with requests, the minimum allowed timeout is hardcoded to be 2.9 seconds. \
Logically, the animation timeout should be at least `2900`, at best `10000` milliseconds (10 seconds) for the animation to look smooth on other clients. \
In the mobile app, the status isn't updated consistently, i.e. the list of server members is updated based on the users actions in the app. Don't be surprised, if the animation doesn't appear smooth, or skips frames. \
^ According to [@pintoso](https://github.com/pintoso)
## 'rich' vs 'raw' editor
Since the lastest version, the plugin now features a new rich editor. It doesn't add functionality, but makes editing your animations a whole lot easier!\
\
The raw editor is just a text input field, where you can edit your animations manually in a json-like format\
(looking at the source code reveals that it's basically json with missing brackets)
## Animations
\
Animations are made in a really simple and easy to understand syntax.
```
"Test (Message)"
"Test (Message)", "� (Symbol)"
"Test (Message)", "emoji (Nitro Symbol)", "000000000000000000 (Nitro Symbol ID)"
"eval new String('test') (Javascript)"
"eval new String('test') (Javascript)", "eval new String('�') (Javascript)"
...
```
## Examples
Switching text:
```
"Text 1"
"Text 2 with emoji", "�"
```
## Discord Nitro Emoji
- Open a discord Chat, type `\`.
<img src="screenshots/nitro0.png">
- Select the emoji you want to include in your status using the emoji picker.
<img src="screenshots/nitro1.png">
- Notice that the message changed to `<:emojiname:emojiid>`. The values inside the brackets (emojiname and emojiid) are the values required for the status.
<img src="screenshots/nitro2.png">
- Edit the settings accordingly
<img src="screenshots/nitro3.png">
### Custom Javascript
Have the current time as your status:
```
"eval let fmt=t=>(t<10?'0':'')+t;let d=new Date();`${fmt(d.getHours())}:${fmt(d.getMinutes())}:${fmt(d.getSeconds())}`;"
```
Have the current time with the corresponding clock symbol as your current status

```
"eval let fmt=t=>(t<10?'0':'')+t;let d=new Date();`${fmt(d.getHours())}:${fmt(d.getMinutes())}:${fmt(d.getSeconds())}`;", "eval ['�','�','�','�','�','�','�','�','�','�','�','�'][((new Date()).getHours()%12)];"
```
BetterDiscord-Animated-Status-master/animated-status.plugin.js
//META{"name":"AnimatedStatus","source":"https://raw.githubusercontent.com/toluschr/BetterDiscord-Animated-Status/master/animated-status.plugin.js","website":"https://github.com/toluschr/BetterDiscord-Animated-Status"}*//
const Editor_Type = {
RICH: 0,
RAW: 1,
};
class AnimatedStatus {
/* BD functions */
getName() {
return "AnimatedStatus";
}
getVersion() {
return "0.11.1";
}
getAuthor() {
return "toluschr";
}
getDescription() {
return "Animate your Discord status";
}
setData(key, value) {
BdApi.setData(this.getName(), key, value);
}
getData(key) {
return BdApi.getData(this.getName(), key);
}
/* Code related to Animations */
load() {
this.kSpacing = "15px";
this.kMinTimeout = 2900;
this.kDefaultEditor = Editor_Type.RICH;
this.animation = this.getData("animation") || [];
this.timeout = this.getData("timeout") || this.kMinTimeout;
this.editor = this.getData("editor") || this.kDefaultEditor;
// Be compatible with older configs
if (typeof this.timeout == "string")
this.timeout = parseInt(this.timeout);
}
start() {
this.Status_Animate();
}
stop() {
clearTimeout(this.loop);
Status.unset();
}
Status_Eval(string) {
try {
return ((string.startsWith("eval ")) ? (eval(string.substr(5))) : (string));
}
catch (e) {
BdApi.showToast(e, {type: "error"});
return "";
}
}
Status_Animate(index = 0) {
if (index >= this.animation.length) index = 0;
if (this.animation[index] == undefined) {
BdApi.showToast("Animated Status: No status set. Go to Settings>Plugins to set a custom animation!");
return;
}
let results = this.animation[index].map(async (element) => this.Status_Eval(element));
Promise.all(results).then(res => {
Status.set(res)
this.loop = setTimeout(() => { this.Status_Animate(index + 1); }, this.timeout);
});
}
// Ui related, but special components
newRawEdit(str = "") {
let out = GUI.newTextarea();
out.style.fontFamily = "SourceCodePro,Consolas,Liberation Mono,Menlo,Courier,monospace";
out.placeholder = '"Test (Message)"\n"Test (Message)", "� (Symbol)"\n"Test (Message)", "emoji (Nitro Symbol)", "000000000000000000 (Nitro Symbol ID)"\n"eval new String(\'test\') (Javascript)"\n"eval new String(\'test\') (Javascript)", "eval new String(\'�\') (Javascript)"\n...';
out.value = str;
return out;
}
newRichRow(text, emoji, optNitroId = undefined) {
let hbox = GUI.newHBox();
let textWidget = GUI.newInput(text);
textWidget.placeholder = "Text";
textWidget.style.marginRight = this.kSpacing;
if (text != undefined) textWidget.value = text;
hbox.appendChild(textWidget);
let emojiWidget = GUI.newInput(emoji);
emojiWidget.placeholder = "� / nitro_name";
emojiWidget.style.width = "140px";
emojiWidget.style.marginRight = this.kSpacing;
if (emoji != undefined) emojiWidget.value = emoji;
hbox.appendChild(emojiWidget);
let optNitroIdWidget = GUI.newInput(optNitroId);
optNitroIdWidget.placeholder = "nitro_id";
optNitroIdWidget.style.width = "150px";
if (optNitroId != undefined) optNitroIdWidget.value = optNitroId;
hbox.appendChild(optNitroIdWidget);
return hbox;
}
// Conversion related
strToJson(str) {
return str.split("\n").filter(i => i).map((element) => JSON.parse(`[${element}]`));
}
jsonToStr(animation) {
if (animation == undefined) return "";
let out = "";
for (let i = 0; i < animation.length; i++) {
out += JSON.stringify(animation[i]).substr(1).slice(0, -1) + "\n";
}
return out;
}
jsonToRichEdit(json) {
let out = document.createElement("div");
for (let i = 0; i < json.length; i++) {
// text is 0, emoji is 1
let row = undefined;
if (json[i].length == 2) row = this.newRichRow(json[i][0], json[i][1]);
else row = this.newRichRow(json[i][0], json[i][1], json[i][2]);
if (i) row.style.marginTop = "15px";
out.appendChild(row);
}
return out;
}
richEditToJson(editor) {
return Array.prototype.slice.call(editor.childNodes).map((element) => {
return Array.prototype.slice.call(element.childNodes)
.filter(e => e.value.length)
.map(e => e.value);
}).filter(e => e.length);
}
// Settings
getSettingsPanel() {
let settings = document.createElement("div");
settings.style.padding = "10px";
// timeout
settings.appendChild(GUI.newLabel("Time per Keyframe (In milliseconds)"));
let timeout = GUI.newInput();
timeout.setAttribute("type", "number");
timeout.addEventListener("focusout", () => {
if (parseInt(timeout.value) < this.kMinTimeout) {
timeout.value = String(this.kMinTimeout);
BdApi.showToast(`Timeout must not be lower than ${this.kMinTimeout}`, {type: "error"});
}
});
timeout.value = String(this.timeout);
timeout.style.marginBottom = this.kSpacing;
settings.appendChild(timeout);
// Animation
settings.appendChild(GUI.newLabel('Animation'));
let animationContainer = document.createElement("div");
animationContainer.marginBottom = this.kSpacing;
settings.appendChild(animationContainer);
// Actions
let actions = GUI.newHBox();
actions.style.marginTop = this.kSpacing;
settings.appendChild(actions);
let actionsRich = GUI.newHBox();
let addStep = GUI.setSuggested(GUI.newButton("+", false));
addStep.title = "Add step to end";
addStep.onclick = () => {
let row = this.newRichRow();
if (edit.childNodes.length) row.style.marginTop = this.kSpacing;
edit.appendChild(row);
}
actionsRich.appendChild(addStep);
let delStep = GUI.setDestructive(GUI.newButton("-", false));
delStep.title = "Remove last step";
delStep.style.marginLeft = this.kSpacing;
delStep.onclick = () => edit.removeChild(edit.childNodes[edit.childNodes.length - 1]);
actionsRich.appendChild(delStep);
let edit = undefined;
if (this.editor == Editor_Type.RICH) {
edit = this.jsonToRichEdit(this.animation);
actionsRich.style.display = "flex";
} else {
edit = this.newRawEdit(this.jsonToStr(this.animation));
actionsRich.style.display = "none";
}
animationContainer.appendChild(edit);
let changeEditMode = GUI.newButton("Change Edit Mode");
actions.appendChild(changeEditMode);
// TODO make this function less bad
changeEditMode.onclick = () => {
this.editor = !this.editor;
let newEdit = undefined;
try {
if (this.editor == Editor_Type.RICH) {
newEdit = this.jsonToRichEdit(this.strToJson(edit.value));
actionsRich.style.display = "flex";
} else {
newEdit = this.newRawEdit(this.jsonToStr(this.richEditToJson(edit)));
actionsRich.style.display = "none";
}
}
catch (e) {
BdApi.showToast(e, {type: "error"});
return;
}
animationContainer.removeChild(edit);
animationContainer.appendChild(newEdit);
edit = newEdit;
};
// Append actions Rich after change edit mode
actionsRich.style.marginLeft = this.kSpacing
actions.appendChild(actionsRich);
// Move save to the right
actions.appendChild(GUI.setExpand(document.createElement("div"), 2));
let save = GUI.newButton("Save");
GUI.setSuggested(save, true);
actions.appendChild(save);
save.onclick = () => {
try {
// Set timeout
this.setData("timeout", parseInt(timeout.value));
this.setData("editor", this.editor);
// Set Animation
if (this.editor == Editor_Type.RICH)
this.setData("animation", this.richEditToJson(edit));
else
this.setData("animation", this.strToJson(edit.value));
}
catch (e) {
BdApi.showToast(e, {type: "error"});
return;
}
// Show Toast
BdApi.showToast("Settings were saved!", {type: "success"});
// Restart
this.load();
this.stop();
this.start();
};
// End
return settings;
}
}
/* Status API */
const Status = {
authToken: Object.values(webpackJsonp.push([ [], { ['']: (_, e, r) => { e.cache = r.c } }, [ [''] ] ]).cache).find(m => m.exports && m.exports.default && m.exports.default.getToken !== void 0).exports.default.getToken(),
strerror: (req) => {
if (req.status < 400)
return undefined;
if (req.status == 401)
return "Invalid AuthToken";
let json = JSON.parse(req.response);
for (const s of ["errors", "custom_status", "text", "_errors", 0, "message"])
if ((json == undefined) || ((json = json[s]) == undefined))
return "Internal. Report at github.com/toluschr/BetterDiscord-Animated-Status";
return json;
},
request: () => {
let req = new XMLHttpRequest();
req.open("PATCH", "/api/v8/users/@me/settings", true);
req.setRequestHeader("authorization", Status.authToken);
req.setRequestHeader("content-type", "application/json");
req.onload = () => {
let err = Status.strerror(req);
if (err != undefined)
BdApi.showToast(`Animated Status: Error: ${err}`, {type: "error"});
};
return req;
},
set: (status) => {
let data = {};
if (status.length == 0) return;
if (status.length >= 1) data.text = status[0];
if (status.length >= 2) data.emoji_name = status[1];
if (status.length >= 3) data.emoji_id = status[2];
Status.request().send(JSON.stringify({custom_status: data}));
},
unset: () => {
Status.request().send('{"custom_status":null}');
}
};
// Used to easily style elements like the 'native' discord ones
const GUI = {
newInput: (text = "") => {
let input = document.createElement("input");
input.className = "inputDefault-_djjkz input-cIJ7To";
input.innerText = text;
return input;
},
newLabel: (text) => {
let label = document.createElement("h5");
label.className = "h5-18_1nd";
label.innerText = text;
return label;
},
newTextarea: () => {
let textarea = document.createElement("textarea");
textarea.className = "input-cIJ7To scrollbarGhostHairline-1mSOM1";
textarea.style.resize = "vertical";
textarea.rows = 4;
return textarea;
},
newButton: (text, filled = true) => {
let button = document.createElement("button");
button.className = "button-38aScr colorBrand-3pXr91 sizeSmall-2cSMqn grow-q77ONN";
if (filled) button.classList.add("lookFilled-1Gx00P");
else button.classList.add("lookOutlined-3sRXeN");
button.innerText = text;
return button;
},
newHBox: () => {
let hbox = document.createElement("div");
hbox.style.display = "flex";
hbox.style.flexDirection = "row";
return hbox;
},
setExpand: (element, value) => {
element.style.flexGrow = value;
return element;
},
setSuggested: (element, value = true) => {
if (value) element.classList.add("colorGreen-29iAKY");
else element.classList.remove("mystyle");
return element;
},
setDestructive: (element, value = true) => {
if (value) element.classList.add("colorRed-1TFJan");
else element.classList.remove("colorRed-1TFJan");
return element;
}
};
BetterDiscord-Animated-Status-master/screenshots/nitro0.png
BetterDiscord-Animated-Status-master/screenshots/nitro1.png
BetterDiscord-Animated-Status-master/screenshots/nitro2.png
BetterDiscord-Animated-Status-master/screenshots/nitro3.png
BetterDiscord-Animated-Status-master/screenshots/rich.png
BetterDiscord-Animated-Status-master/screenshots/settings.png
BetterDiscord-Animated-Status-master/screenshots/status_clock.png