mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-19 03:17:02 -04:00
New plugin: VoiceMessages (#1380)
Co-authored-by: V <vendicated@riseup.net> Co-authored-by: Justice Almanzar <superdash993@gmail.com>
This commit is contained in:
parent
198b35ffdc
commit
8620a1d86d
16 changed files with 660 additions and 37 deletions
|
@ -32,4 +32,5 @@ export const enum IpcEvents {
|
|||
OPEN_MONACO_EDITOR = "VencordOpenMonacoEditor",
|
||||
|
||||
OPEN_IN_APP__RESOLVE_REDIRECT = "VencordOIAResolveRedirect",
|
||||
VOICE_MESSAGES_READ_RECORDING = "VencordVMReadRecording",
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { React, useEffect, useReducer, useState } from "@webpack/common";
|
||||
import { React, useEffect, useMemo, useReducer, useState } from "@webpack/common";
|
||||
|
||||
import { makeLazy } from "./lazy";
|
||||
import { checkIntersecting } from "./misc";
|
||||
|
@ -135,3 +135,24 @@ export function LazyComponent<T extends object = any>(factory: () => React.Compo
|
|||
return <Component {...props} />;
|
||||
};
|
||||
}
|
||||
|
||||
interface TimerOpts {
|
||||
interval?: number;
|
||||
deps?: unknown[];
|
||||
}
|
||||
|
||||
export function useTimer({ interval = 1000, deps = [] }: TimerOpts) {
|
||||
const [time, setTime] = useState(0);
|
||||
const start = useMemo(() => Date.now(), deps);
|
||||
|
||||
useEffect(() => {
|
||||
const intervalId = setInterval(() => setTime(Date.now() - start), interval);
|
||||
|
||||
return () => {
|
||||
setTime(0);
|
||||
clearInterval(intervalId);
|
||||
};
|
||||
}, deps);
|
||||
|
||||
return time;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import { deflateSync, inflateSync } from "fflate";
|
|||
|
||||
import { getCloudAuth, getCloudUrl } from "./cloud";
|
||||
import { Logger } from "./Logger";
|
||||
import { saveFile } from "./web";
|
||||
import { chooseFile, saveFile } from "./web";
|
||||
|
||||
export async function importSettings(data: string) {
|
||||
try {
|
||||
|
@ -91,30 +91,20 @@ export async function uploadSettingsBackup(showToast = true): Promise<void> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.style.display = "none";
|
||||
input.accept = "application/json";
|
||||
input.onchange = async () => {
|
||||
const file = input.files?.[0];
|
||||
if (!file) return;
|
||||
const file = await chooseFile("application/json");
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = async () => {
|
||||
try {
|
||||
await importSettings(reader.result as string);
|
||||
if (showToast) toastSuccess();
|
||||
} catch (err) {
|
||||
new Logger("SettingsSync").error(err);
|
||||
if (showToast) toastFailure(err);
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
const reader = new FileReader();
|
||||
reader.onload = async () => {
|
||||
try {
|
||||
await importSettings(reader.result as string);
|
||||
if (showToast) toastSuccess();
|
||||
} catch (err) {
|
||||
new Logger("SettingsSync").error(err);
|
||||
if (showToast) toastFailure(err);
|
||||
}
|
||||
};
|
||||
|
||||
document.body.appendChild(input);
|
||||
input.click();
|
||||
setImmediate(() => document.body.removeChild(input));
|
||||
reader.readAsText(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prompts the user to save a file to their system
|
||||
* @param file The file to save
|
||||
*/
|
||||
export function saveFile(file: File) {
|
||||
const a = document.createElement("a");
|
||||
a.href = URL.createObjectURL(file);
|
||||
|
@ -28,3 +32,24 @@ export function saveFile(file: File) {
|
|||
document.body.removeChild(a);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompts the user to choose a file from their system
|
||||
* @param mimeTypes A comma separated list of mime types to accept, see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept#unique_file_type_specifiers
|
||||
* @returns A promise that resolves to the chosen file or null if the user cancels
|
||||
*/
|
||||
export function chooseFile(mimeTypes: string) {
|
||||
return new Promise<File | null>(resolve => {
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.style.display = "none";
|
||||
input.accept = mimeTypes;
|
||||
input.onchange = async () => {
|
||||
resolve(input.files?.[0] ?? null);
|
||||
};
|
||||
|
||||
document.body.appendChild(input);
|
||||
input.click();
|
||||
setImmediate(() => document.body.removeChild(input));
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue