talon-one/.obsidian/plugins/obsidian-discordrpc/main.js

1772 lines
195 KiB
JavaScript
Raw Normal View History

'use strict';
var require$$0 = require('electron');
var EventEmitter = require('events');
var require$$0$1 = require('timers');
var net = require('net');
var obsidian = require('obsidian');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$1);
var net__default = /*#__PURE__*/_interopDefaultLegacy(net);
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
var _nodeResolve_empty = {};
var _nodeResolve_empty$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
'default': _nodeResolve_empty
});
function createCommonjsModule(fn, basedir, module) {
return module = {
path: basedir,
exports: {},
require: function (path, base) {
return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
}
}, fn(module, module.exports), module.exports;
}
function getAugmentedNamespace(n) {
if (n.__esModule) return n;
var a = Object.defineProperty({}, '__esModule', {value: true});
Object.keys(n).forEach(function (k) {
var d = Object.getOwnPropertyDescriptor(n, k);
Object.defineProperty(a, k, d.get ? d : {
enumerable: true,
get: function () {
return n[k];
}
});
});
return a;
}
function commonjsRequire () {
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
}
var require$$1 = /*@__PURE__*/getAugmentedNamespace(_nodeResolve_empty$1);
let register;
try {
const { app } = require$$0__default['default'];
register = app.setAsDefaultProtocolClient.bind(app);
} catch (err) {
try {
register = require$$1;
} catch (e) {} // eslint-disable-line no-empty
}
if (typeof register !== 'function') {
register = () => false;
}
function pid() {
if (typeof process !== 'undefined') {
return process.pid;
}
return null;
}
const uuid4122 = () => {
let uuid = '';
for (let i = 0; i < 32; i += 1) {
if (i === 8 || i === 12 || i === 16 || i === 20) {
uuid += '-';
}
let n;
if (i === 12) {
n = 4;
} else {
const random = Math.random() * 16 | 0;
if (i === 16) {
n = (random & 3) | 0;
} else {
n = random;
}
}
uuid += n.toString(16);
}
return uuid;
};
var util = {
pid,
register,
uuid: uuid4122,
};
var browser$2 = createCommonjsModule(function (module, exports) {
// ref: https://github.com/tc39/proposal-global
var getGlobal = function () {
// the only reliable means to get the global object is
// `Function('return this')()`
// However, this causes CSP violations in Chrome apps.
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};
var global = getGlobal();
module.exports = exports = global.fetch;
// Needed for TypeScript and Webpack.
if (global.fetch) {
exports.default = global.fetch.bind(global);
}
exports.Headers = global.Headers;
exports.Request = global.Request;
exports.Response = global.Response;
});
const { uuid: uuid$1 } = util;
const OPCodes = {
HANDSHAKE: 0,
FRAME: 1,
CLOSE: 2,
PING: 3,
PONG: 4,
};
function getIPCPath(id) {
if (process.platform === 'win32') {
return `\\\\?\\pipe\\discord-ipc-${id}`;
}
const { env: { XDG_RUNTIME_DIR, TMPDIR, TMP, TEMP } } = process;
const prefix = XDG_RUNTIME_DIR || TMPDIR || TMP || TEMP || '/tmp';
return `${prefix.replace(/\/$/, '')}/discord-ipc-${id}`;
}
function getIPC(id = 0) {
return new Promise((resolve, reject) => {
const path = getIPCPath(id);
const onerror = () => {
if (id < 10) {
resolve(getIPC(id + 1));
} else {
reject(new Error('Could not connect'));
}
};
const sock = net__default['default'].createConnection(path, () => {
sock.removeListener('error', onerror);
resolve(sock);
});
sock.once('error', onerror);
});
}
async function findEndpoint(tries = 0) {
if (tries > 30) {
throw new Error('Could not find endpoint');
}
const endpoint = `http://127.0.0.1:${6463 + (tries % 10)}`;
try {
const r = await browser$2(endpoint);
if (r.status === 404) {
return endpoint;
}
return findEndpoint(tries + 1);
} catch (e) {
return findEndpoint(tries + 1);
}
}
function encode(op, data) {
data = JSON.stringify(data);
const len = Buffer.byteLength(data);
const packet = Buffer.alloc(8 + len);
packet.writeInt32LE(op, 0);
packet.writeInt32LE(len, 4);
packet.write(data, 8, len);
return packet;
}
const working = {
full: '',
op: undefined,
};
function decode(socket, callback) {
const packet = socket.read();
if (!packet) {
return;
}
let { op } = working;
let raw;
if (working.full === '') {
op = working.op = packet.readInt32LE(0);
const len = packet.readInt32LE(4);
raw = packet.slice(8, len + 8);
} else {
raw = packet.toString();
}
try {
const data = JSON.parse(working.full + raw);
callback({ op, data }); // eslint-disable-line callback-return
working.full = '';
working.op = undefined;
} catch (err) {
working.full += raw;
}
decode(socket, callback);
}
class IPCTransport extends EventEmitter__default['default'] {
constructor(client) {
super();
this.client = client;
this.socket = null;
}
async connect() {
const socket = this.socket = await getIPC();
socket.on('close', this.onClose.bind(this));
socket.on('error', this.onClose.bind(this));
this.emit('open');
socket.write(encode(OPCodes.HANDSHAKE, {
v: 1,
client_id: this.client.clientId,
}));
socket.pause();
socket.on('readable', () => {
decode(socket, ({ op, data }) => {
switch (op) {
case OPCodes.PING:
this.send(data, OPCodes.PONG);
break;
case OPCodes.FRAME:
if (!data) {
return;
}
if (data.cmd === 'AUTHORIZE' && data.evt !== 'ERROR') {
findEndpoint()
.then((endpoint) => {
this.client.request.endpoint = endpoint;
})
.catch((e) => {
this.client.emit('error', e);
});
}
this.emit('message', data);
break;
case OPCodes.CLOSE:
this.emit('close', data);
break;
default:
break;
}
});
});
}
onClose(e) {
this.emit('close', e);
}
send(data, op = OPCodes.FRAME) {
this.socket.write(encode(op, data));
}
async close() {
return new Promise((r) => {
this.once('close', r);
this.send({}, OPCodes.CLOSE);
this.socket.end();
});
}
ping() {
this.send(uuid$1(), OPCodes.PING);
}
}
var ipc = IPCTransport;
var encode_1 = encode;
var decode_1 = decode;
ipc.encode = encode_1;
ipc.decode = decode_1;
function keyMirror(arr) {
const tmp = {};
for (const value of arr) {
tmp[value] = value;
}
return tmp;
}
var browser$1 = typeof window !== 'undefined';
var RPCCommands$1 = keyMirror([
'DISPATCH',
'AUTHORIZE',
'AUTHENTICATE',
'GET_GUILD',
'GET_GUILDS',
'GET_CHANNEL',
'GET_CHANNELS',
'CREATE_CHANNEL_INVITE',
'GET_RELATIONSHIPS',
'GET_USER',
'SUBSCRIBE',
'UNSUBSCRIBE',
'SET_USER_VOICE_SETTINGS',
'SET_USER_VOICE_SETTINGS_2',
'SELECT_VOICE_CHANNEL',
'GET_SELECTED_VOICE_CHANNEL',
'SELECT_TEXT_CHANNEL',
'GET_VOICE_SETTINGS',
'SET_VOICE_SETTINGS_2',
'SET_VOICE_SETTINGS',
'CAPTURE_SHORTCUT',
'SET_ACTIVITY',
'SEND_ACTIVITY_JOIN_INVITE',
'CLOSE_ACTIVITY_JOIN_REQUEST',
'ACTIVITY_INVITE_USER',
'ACCEPT_ACTIVITY_INVITE',
'INVITE_BROWSER',
'DEEP_LINK',
'CONNECTIONS_CALLBACK',
'BRAINTREE_POPUP_BRIDGE_CALLBACK',
'GIFT_CODE_BROWSER',
'GUILD_TEMPLATE_BROWSER',
'OVERLAY',
'BROWSER_HANDOFF',
'SET_CERTIFIED_DEVICES',
'GET_IMAGE',
'CREATE_LOBBY',
'UPDATE_LOBBY',
'DELETE_LOBBY',
'UPDATE_LOBBY_MEMBER',
'CONNECT_TO_LOBBY',
'DISCONNECT_FROM_LOBBY',
'SEND_TO_LOBBY',
'SEARCH_LOBBIES',
'CONNECT_TO_LOBBY_VOICE',
'DISCONNECT_FROM_LOBBY_VOICE',
'SET_OVERLAY_LOCKED',
'OPEN_OVERLAY_ACTIVITY_INVITE',
'OPEN_OVERLAY_GUILD_INVITE',
'OPEN_OVERLAY_VOICE_SETTINGS',
'VALIDATE_APPLICATION',
'GET_ENTITLEMENT_TICKET',
'GET_APPLICATION_TICKET',
'START_PURCHASE',
'GET_SKUS',
'GET_ENTITLEMENTS',
'GET_NETWORKING_CONFIG',
'NETWORKING_SYSTEM_METRICS',
'NETWORKING_PEER_METRICS',
'NETWORKING_CREATE_TOKEN',
'SET_USER_ACHIEVEMENT',
'GET_USER_ACHIEVEMENTS',
]);
var RPCEvents$1 = keyMirror([
'CURRENT_USER_UPDATE',
'GUILD_STATUS',
'GUILD_CREATE',
'CHANNEL_CREATE',
'RELATIONSHIP_UPDATE',
'VOICE_CHANNEL_SELECT',
'VOICE_STATE_CREATE',
'VOICE_STATE_DELETE',
'VOICE_STATE_UPDATE',
'VOICE_SETTINGS_UPDATE',
'VOICE_SETTINGS_UPDATE_2',
'VOICE_CONNECTION_STATUS',
'SPEAKING_START',
'SPEAKING_STOP',
'GAME_JOIN',
'GAME_SPECTATE',
'ACTIVITY_JOIN',
'ACTIVITY_JOIN_REQUEST',
'ACTIVITY_SPECTATE',
'ACTIVITY_INVITE',
'NOTIFICATION_CREATE',
'MESSAGE_CREATE',
'MESSAGE_UPDATE',
'MESSAGE_DELETE',
'LOBBY_DELETE',
'LOBBY_UPDATE',
'LOBBY_MEMBER_CONNECT',
'LOBBY_MEMBER_DISCONNECT',
'LOBBY_MEMBER_UPDATE',
'LOBBY_MESSAGE',
'CAPTURE_SHORTCUT_CHANGE',
'OVERLAY',
'OVERLAY_UPDATE',
'ENTITLEMENT_CREATE',
'ENTITLEMENT_DELETE',
'USER_ACHIEVEMENT_UPDATE',
'READY',
'ERROR',
]);
var RPCErrors = {
CAPTURE_SHORTCUT_ALREADY_LISTENING: 5004,
GET_GUILD_TIMED_OUT: 5002,
INVALID_ACTIVITY_JOIN_REQUEST: 4012,
INVALID_ACTIVITY_SECRET: 5005,
INVALID_CHANNEL: 4005,
INVALID_CLIENTID: 4007,
INVALID_COMMAND: 4002,
INVALID_ENTITLEMENT: 4015,
INVALID_EVENT: 4004,
INVALID_GIFT_CODE: 4016,
INVALID_GUILD: 4003,
INVALID_INVITE: 4011,
INVALID_LOBBY: 4013,
INVALID_LOBBY_SECRET: 4014,
INVALID_ORIGIN: 4008,
INVALID_PAYLOAD: 4000,
INVALID_PERMISSIONS: 4006,
INVALID_TOKEN: 4009,
INVALID_USER: 4010,
LOBBY_FULL: 5007,
NO_ELIGIBLE_ACTIVITY: 5006,
OAUTH2_ERROR: 5000,
PURCHASE_CANCELED: 5008,
PURCHASE_ERROR: 5009,
RATE_LIMITED: 5011,
SELECT_CHANNEL_TIMED_OUT: 5001,
SELECT_VOICE_FORCE_REQUIRED: 5003,
SERVICE_UNAVAILABLE: 1001,
TRANSACTION_ABORTED: 1002,
UNAUTHORIZED_FOR_ACHIEVEMENT: 5010,
UNKNOWN_ERROR: 1000,
};
var RPCCloseCodes = {
CLOSE_NORMAL: 1000,
CLOSE_UNSUPPORTED: 1003,
CLOSE_ABNORMAL: 1006,
INVALID_CLIENTID: 4000,
INVALID_ORIGIN: 4001,
RATELIMITED: 4002,
TOKEN_REVOKED: 4003,
INVALID_VERSION: 4004,
INVALID_ENCODING: 4005,
};
var LobbyTypes = {
PRIVATE: 1,
PUBLIC: 2,
};
var RelationshipTypes$1 = {
NONE: 0,
FRIEND: 1,
BLOCKED: 2,
PENDING_INCOMING: 3,
PENDING_OUTGOING: 4,
IMPLICIT: 5,
};
var constants = {
browser: browser$1,
RPCCommands: RPCCommands$1,
RPCEvents: RPCEvents$1,
RPCErrors: RPCErrors,
RPCCloseCodes: RPCCloseCodes,
LobbyTypes: LobbyTypes,
RelationshipTypes: RelationshipTypes$1
};
const { browser } = constants;
// eslint-disable-next-line
const WebSocket = browser ? window.WebSocket : require$$1;
const pack = (d) => JSON.stringify(d);
const unpack = (s) => JSON.parse(s);
class WebSocketTransport extends EventEmitter__default['default'] {
constructor(client) {
super();
this.client = client;
this.ws = null;
this.tries = 0;
}
async connect() {
const port = 6463 + (this.tries % 10);
this.tries += 1;
this.ws = new WebSocket(
`ws://127.0.0.1:${port}/?v=1&client_id=${this.client.clientId}`,
browser ? undefined : { origin: this.client.options.origin },
);
this.ws.onopen = this.onOpen.bind(this);
this.ws.onclose = this.onClose.bind(this);
this.ws.onerror = this.onError.bind(this);
this.ws.onmessage = this.onMessage.bind(this);
}
onOpen() {
this.emit('open');
}
onClose(event) {
if (!event.wasClean) {
return;
}
this.emit('close', event);
}
onError(event) {
try {
this.ws.close();
} catch {} // eslint-disable-line no-empty
if (this.tries > 20) {
this.emit('error', event.error);
} else {
setTimeout(() => {
this.connect();
}, 250);
}
}
onMessage(event) {
this.emit('message', unpack(event.data));
}
send(data) {
this.ws.send(pack(data));
}
ping() {} // eslint-disable-line no-empty-function
close() {
return new Promise((r) => {
this.once('close', r);
this.ws.close();
});
}
}
var websocket = WebSocketTransport;
var transports = {
ipc: ipc,
websocket: websocket,
};
const { setTimeout: setTimeout$1, clearTimeout } = require$$0__default$1['default'];
const { RPCCommands, RPCEvents, RelationshipTypes } = constants;
const { pid: getPid, uuid } = util;
function subKey(event, args) {
return `${event}${JSON.stringify(args)}`;
}
/**
* @typedef {RPCClientOptions}
* @extends {ClientOptions}
* @prop {string} transport RPC transport. one of `ipc` or `websocket`
*/
/**
* The main hub for interacting with Discord RPC
* @extends {BaseClient}
*/
class RPCClient extends EventEmitter__default['default'] {
/**
* @param {RPCClientOptions} [options] Options for the client.
* You must provide a transport
*/
constructor(options = {}) {
super();
this.options = options;
this.accessToken = null;
this.clientId = null;
/**
* Application used in this client
* @type {?ClientApplication}
*/
this.application = null;
/**
* User used in this application
* @type {?User}
*/
this.user = null;
const Transport = transports[options.transport];
if (!Transport) {
throw new TypeError('RPC_INVALID_TRANSPORT', options.transport);
}
this.fetch = (method, path, { data, query } = {}) =>
browser$2(`${this.fetch.endpoint}${path}${query ? new URLSearchParams(query) : ''}`, {
method,
body: data,
headers: {
Authorization: `Bearer ${this.accessToken}`,
},
}).then(async (r) => {
const body = await r.json();
if (!r.ok) {
const e = new Error(r.status);
e.body = body;
throw e;
}
return body;
});
this.fetch.endpoint = 'https://discord.com/api';
/**
* Raw transport userd
* @type {RPCTransport}
* @private
*/
this.transport = new Transport(this);
this.transport.on('message', this._onRpcMessage.bind(this));
/**
* Map of nonces being expected from the transport
* @type {Map}
* @private
*/
this._expecting = new Map();
/**
* Map of current subscriptions
* @type {Map}
* @private
*/
this._subscriptions = new Map();
this._connectPromise = undefined;
}
/**
* Search and connect to RPC
*/
connect(clientId) {
if (this._connectPromise) {
return this._connectPromise;
}
this._connectPromise = new Promise((resolve, reject) => {
this.clientId = clientId;
const timeout = setTimeout$1(() => reject(new Error('RPC_CONNECTION_TIMEOUT')), 10e3);
timeout.unref();
this.once('connected', () => {
clearTimeout(timeout);
resolve(this);
});
this.transport.once('close', () => {
this._expecting.forEach((e) => {
e.reject(new Error('connection closed'));
});
this.emit('disconnected');
reject(new Error('connection closed'));
});
this.transport.connect().catch(reject);
});
return this._connectPromise;
}
/**
* @typedef {RPCLoginOptions}
* @param {string} clientId Client ID
* @param {string} [clientSecret] Client secret
* @param {string} [accessToken] Access token
* @param {string} [rpcToken] RPC token
* @param {string} [tokenEndpoint] Token endpoint
* @param {string[]} [scopes] Scopes to authorize with
*/
/**
* Performs authentication flow. Automatically calls Client#connect if needed.
* @param {RPCLoginOptions} options Options for authentication.
* At least one property must be provided to perform login.
* @example client.login({ clientId: '1234567', clientSecret: 'abcdef123' });
* @returns {Promise<RPCClient>}
*/
async login(options = {}) {
let { clientId, accessToken } = options;
await this.connect(clientId);
if (!options.scopes) {
this.emit('ready');
return this;
}
if (!accessToken) {
accessToken = await this.authorize(options);
}
return this.authenticate(accessToken);
}
/**
* Request
* @param {string} cmd Command
* @param {Object} [args={}] Arguments
* @param {string} [evt] Event
* @returns {Promise}
* @private
*/
request(cmd, args, evt) {
return new Promise((resolve, reject) => {
const nonce = uuid();
this.transport.send({ cmd, args, evt, nonce });
this._expecting.set(nonce, { resolve, reject });
});
}
/**
* Message handler
* @param {Object} message message
* @private
*/
_onRpcMessage(message) {
if (message.cmd === RPCCommands.DISPATCH && message.evt === RPCEvents.READY) {
if (message.data.user) {
this.user = message.data.user;
}
this.emit('connected');
} else if (this._expecting.has(message.nonce)) {
const { resolve, reject } = this._expecting.get(message.nonce);
if (message.evt === 'ERROR') {
const e = new Error(message.data.message);
e.code = message.data.code;
e.data = message.data;
reject(e);
} else {
resolve(message.data);
}
this._expecting.delete(message.nonce);
} else {
const subid = subKey(message.evt, message.args);
if (!this._subscriptions.has(subid)) {
return;
}
this._subscriptions.get(subid)(message.data);
}
}
/**
* Authorize
* @param {Object} options options
* @returns {Promise}
* @private
*/
async authorize({ scopes, clientSecret, rpcToken, redirectUri } = {}) {
if (clientSecret && rpcToken === true) {
const body = await this.fetch('POST', '/oauth2/token/rpc', {
data: new URLSearchParams({
client_id: this.clientId,
client_secret: clientSecret,
}),
});
rpcToken = body.rpc_token;
}
const { code } = await this.request('AUTHORIZE', {
scopes,
client_id: this.clientId,
rpc_token: rpcToken,
});
const response = await this.fetch('POST', '/oauth2/token', {
data: new URLSearchParams({
client_id: this.clientId,
client_secret: clientSecret,
code,
grant_type: 'authorization_code',
redirect_uri: redirectUri,
}),
});
return response.access_token;
}
/**
* Authenticate
* @param {string} accessToken access token
* @returns {Promise}
* @private
*/
authenticate(accessToken) {
return this.request('AUTHENTICATE', { access_token: accessToken })
.then(({ application, user }) => {
this.accessToken = accessToken;
this.application = application;
this.user = user;
this.emit('ready');
return this;
});
}
/**
* Fetch a guild
* @param {Snowflake} id Guild ID
* @param {number} [timeout] Timeout request
* @returns {Promise<Guild>}
*/
getGuild(id, timeout) {
return this.request(RPCCommands.GET_GUILD, { guild_id: id, timeout });
}
/**
* Fetch all guilds
* @param {number} [timeout] Timeout request
* @returns {Promise<Collection<Snowflake, Guild>>}
*/
getGuilds(timeout) {
return this.request(RPCCommands.GET_GUILDS, { timeout });
}
/**
* Get a channel
* @param {Snowflake} id Channel ID
* @param {number} [timeout] Timeout request
* @returns {Promise<Channel>}
*/
getChannel(id, timeout) {
return this.request(RPCCommands.GET_CHANNEL, { channel_id: id, timeout });
}
/**
* Get all channels
* @param {Snowflake} [id] Guild ID
* @param {number} [timeout] Timeout request
* @returns {Promise<Collection<Snowflake, Channel>>}
*/
async getChannels(id, timeout) {
const { channels } = await this.request(RPCCommands.GET_CHANNELS, {
timeout,
guild_id: id,
});
return channels;
}
/**
* @typedef {CertifiedDevice}
* @prop {string} type One of `AUDIO_INPUT`, `AUDIO_OUTPUT`, `VIDEO_INPUT`
* @prop {string} uuid This device's Windows UUID
* @prop {object} vendor Vendor information
* @prop {string} vendor.name Vendor's name
* @prop {string} vendor.url Vendor's url
* @prop {object} model Model information
* @prop {string} model.name Model's name
* @prop {string} model.url Model's url
* @prop {string[]} related Array of related product's Windows UUIDs
* @prop {boolean} echoCancellation If the device has echo cancellation
* @prop {boolean} noiseSuppression If the device has noise suppression
* @prop {boolean} automaticGainControl If the device has automatic gain control
* @prop {boolean} hardwareMute If the device has a hardware mute
*/
/**
* Tell discord which devices are certified
* @param {CertifiedDevice[]} devices Certified devices to send to discord
* @returns {Promise}
*/
setCertifiedDevices(devices) {
return this.request(RPCCommands.SET_CERTIFIED_DEVICES, {
devices: devices.map((d) => ({
type: d.type,
id: d.uuid,
vendor: d.vendor,
model: d.model,
related: d.related,
echo_cancellation: d.echoCancellation,
noise_suppression: d.noiseSuppression,
automatic_gain_control: d.automaticGainControl,
hardware_mute: d.hardwareMute,
})),
});
}
/**
* @typedef {UserVoiceSettings}
* @prop {Snowflake} id ID of the user these settings apply to
* @prop {?Object} [pan] Pan settings, an object with `left` and `right` set between
* 0.0 and 1.0, inclusive
* @prop {?number} [volume=100] The volume
* @prop {bool} [mute] If the user is muted
*/
/**
* Set the voice settings for a user, by id
* @param {Snowflake} id ID of the user to set
* @param {UserVoiceSettings} settings Settings
* @returns {Promise}
*/
setUserVoiceSettings(id, settings) {
return this.request(RPCCommands.SET_USER_VOICE_SETTINGS, {
user_id: id,
pan: settings.pan,
mute: settings.mute,
volume: settings.volume,
});
}
/**
* Move the user to a voice channel
* @param {Snowflake} id ID of the voice channel
* @param {Object} [options] Options
* @param {number} [options.timeout] Timeout for the command
* @param {boolean} [options.force] Force this move. This should only be done if you
* have explicit permission from the user.
* @returns {Promise}
*/
selectVoiceChannel(id, { timeout, force = false } = {}) {
return this.request(RPCCommands.SELECT_VOICE_CHANNEL, { channel_id: id, timeout, force });
}
/**
* Move the user to a text channel
* @param {Snowflake} id ID of the voice channel
* @param {Object} [options] Options
* @param {number} [options.timeout] Timeout for the command
* have explicit permission from the user.
* @returns {Promise}
*/
selectTextChannel(id, { timeout } = {}) {
return this.request(RPCCommands.SELECT_TEXT_CHANNEL, { channel_id: id, timeout });
}
/**
* Get current voice settings
* @returns {Promise}
*/
getVoiceSettings() {
return this.request(RPCCommands.GET_VOICE_SETTINGS)
.then((s) => ({
automaticGainControl: s.automatic_gain_control,
echoCancellation: s.echo_cancellation,
noiseSuppression: s.noise_suppression,
qos: s.qos,
silenceWarning: s.silence_warning,
deaf: s.deaf,
mute: s.mute,
input: {
availableDevices: s.input.available_devices,
device: s.input.device_id,
volume: s.input.volume,
},
output: {
availableDevices: s.output.available_devices,
device: s.output.device_id,
volume: s.output.volume,
},
mode: {
type: s.mode.type,
autoThreshold: s.mode.auto_threshold,
threshold: s.mode.threshold,
shortcut: s.mode.shortcut,
delay: s.mode.delay,
},
}));
}
/**
* Set current voice settings, overriding the current settings until this session disconnects.
* This also locks the settings for any other rpc sessions which may be connected.
* @param {Object} args Settings
* @returns {Promise}
*/
setVoiceSettings(args) {
return this.request(RPCCommands.SET_VOICE_SETTINGS, {
automatic_gain_control: args.automaticGainControl,
echo_cancellation: args.echoCancellation,
noise_suppression: args.noiseSuppression,
qos: args.qos,
silence_warning: args.silenceWarning,
deaf: args.deaf,
mute: args.mute,
input: args.input ? {
device_id: args.input.device,
volume: args.input.volume,
} : undefined,
output: args.output ? {
device_id: args.output.device,
volume: args.output.volume,
} : undefined,
mode: args.mode ? {
mode: args.mode.type,
auto_threshold: args.mode.autoThreshold,
threshold: args.mode.threshold,
shortcut: args.mode.shortcut,
delay: args.mode.delay,
} : undefined,
});
}
/**
* Capture a shortcut using the client
* The callback takes (key, stop) where `stop` is a function that will stop capturing.
* This `stop` function must be called before disconnecting or else the user will have
* to restart their client.
* @param {Function} callback Callback handling keys
* @returns {Promise<Function>}
*/
captureShortcut(callback) {
const subid = subKey(RPCEvents.CAPTURE_SHORTCUT_CHANGE);
const stop = () => {
this._subscriptions.delete(subid);
return this.request(RPCCommands.CAPTURE_SHORTCUT, { action: 'STOP' });
};
this._subscriptions.set(subid, ({ shortcut }) => {
callback(shortcut, stop);
});
return this.request(RPCCommands.CAPTURE_SHORTCUT, { action: 'START' })
.then(() => stop);
}
/**
* Sets the presence for the logged in user.
* @param {object} args The rich presence to pass.
* @param {number} [pid] The application's process ID. Defaults to the executing process' PID.
* @returns {Promise}
*/
setActivity(args = {}, pid = getPid()) {
let timestamps;
let assets;
let party;
let secrets;
if (args.startTimestamp || args.endTimestamp) {
timestamps = {
start: args.startTimestamp,
end: args.endTimestamp,
};
if (timestamps.start instanceof Date) {
timestamps.start = Math.round(timestamps.start.getTime());
}
if (timestamps.end instanceof Date) {
timestamps.end = Math.round(timestamps.end.getTime());
}
if (timestamps.start > 2147483647000) {
throw new RangeError('timestamps.start must fit into a unix timestamp');
}
if (timestamps.end > 2147483647000) {
throw new RangeError('timestamps.end must fit into a unix timestamp');
}
}
if (
args.largeImageKey || args.largeImageText
|| args.smallImageKey || args.smallImageText
) {
assets = {
large_image: args.largeImageKey,
large_text: args.largeImageText,
small_image: args.smallImageKey,
small_text: args.smallImageText,
};
}
if (args.partySize || args.partyId || args.partyMax) {
party = { id: args.partyId };
if (args.partySize || args.partyMax) {
party.size = [args.partySize, args.partyMax];
}
}
if (args.matchSecret || args.joinSecret || args.spectateSecret) {
secrets = {
match: args.matchSecret,
join: args.joinSecret,
spectate: args.spectateSecret,
};
}
return this.request(RPCCommands.SET_ACTIVITY, {
pid,
activity: {
state: args.state,
details: args.details,
timestamps,
assets,
party,
secrets,
buttons: args.buttons,
instance: !!args.instance,
},
});
}
/**
* Clears the currently set presence, if any. This will hide the "Playing X" message
* displayed below the user's name.
* @param {number} [pid] The application's process ID. Defaults to the executing process' PID.
* @returns {Promise}
*/
clearActivity(pid = getPid()) {
return this.request(RPCCommands.SET_ACTIVITY, {
pid,
});
}
/**
* Invite a user to join the game the RPC user is currently playing
* @param {User} user The user to invite
* @returns {Promise}
*/
sendJoinInvite(user) {
return this.request(RPCCommands.SEND_ACTIVITY_JOIN_INVITE, {
user_id: user.id || user,
});
}
/**
* Request to join the game the user is playing
* @param {User} user The user whose game you want to request to join
* @returns {Promise}
*/
sendJoinRequest(user) {
return this.request(RPCCommands.SEND_ACTIVITY_JOIN_REQUEST, {
user_id: user.id || user,
});
}
/**
* Reject a join request from a user
* @param {User} user The user whose request you wish to reject
* @returns {Promise}
*/
closeJoinRequest(user) {
return this.request(RPCCommands.CLOSE_ACTIVITY_JOIN_REQUEST, {
user_id: user.id || user,
});
}
createLobby(type, capacity, metadata) {
return this.request(RPCCommands.CREATE_LOBBY, {
type,
capacity,
metadata,
});
}
updateLobby(lobby, { type, owner, capacity, metadata } = {}) {
return this.request(RPCCommands.UPDATE_LOBBY, {
id: lobby.id || lobby,
type,
owner_id: (owner && owner.id) || owner,
capacity,
metadata,
});
}
deleteLobby(lobby) {
return this.request(RPCCommands.DELETE_LOBBY, {
id: lobby.id || lobby,
});
}
connectToLobby(id, secret) {
return this.request(RPCCommands.CONNECT_TO_LOBBY, {
id,
secret,
});
}
sendToLobby(lobby, data) {
return this.request(RPCCommands.SEND_TO_LOBBY, {
id: lobby.id || lobby,
data,
});
}
disconnectFromLobby(lobby) {
return this.request(RPCCommands.DISCONNECT_FROM_LOBBY, {
id: lobby.id || lobby,
});
}
updateLobbyMember(lobby, user, metadata) {
return this.request(RPCCommands.UPDATE_LOBBY_MEMBER, {
lobby_id: lobby.id || lobby,
user_id: user.id || user,
metadata,
});
}
getRelationships() {
const types = Object.keys(RelationshipTypes);
return this.request(RPCCommands.GET_RELATIONSHIPS)
.then((o) => o.relationships.map((r) => ({
...r,
type: types[r.type],
})));
}
/**
* Subscribe to an event
* @param {string} event Name of event e.g. `MESSAGE_CREATE`
* @param {Object} [args] Args for event e.g. `{ channel_id: '1234' }`
* @param {Function} callback Callback when an event for the subscription is triggered
* @returns {Promise<Object>}
*/
subscribe(event, args, callback) {
if (!callback && typeof args === 'function') {
callback = args;
args = undefined;
}
return this.request(RPCCommands.SUBSCRIBE, args, event).then(() => {
const subid = subKey(event, args);
this._subscriptions.set(subid, callback);
return {
unsubscribe: () => this.request(RPCCommands.UNSUBSCRIBE, args, event)
.then(() => this._subscriptions.delete(subid)),
};
});
}
/**
* Destroy the client
*/
async destroy() {
await this.transport.close();
}
}
var client = RPCClient;
var src = {
Client: client,
register(id) {
return util.register(`discord-${id}`);
},
};
var Logger = /** @class */ (function () {
function Logger() {
this.plugin = this.plugin;
}
Logger.prototype.log = function (message, showPopups) {
if (showPopups) {
new obsidian.Notice(message);
}
console.log("discordrpc: " + message);
};
Logger.prototype.logIgnoreNoNotice = function (message) {
new obsidian.Notice(message);
console.log("discordrpc: " + message);
};
return Logger;
}());
var DiscordRPCSettings = /** @class */ (function () {
function DiscordRPCSettings() {
this.showVaultName = true;
this.showCurrentFileName = true;
this.showPopups = true;
this.customVaultName = "";
this.showFileExtension = false;
this.useLoadedTime = false;
this.connectOnStart = true;
this.autoHideStatusBar = true;
}
return DiscordRPCSettings;
}());
var PluginState;
(function (PluginState) {
PluginState[PluginState["connected"] = 0] = "connected";
PluginState[PluginState["connecting"] = 1] = "connecting";
PluginState[PluginState["disconnected"] = 2] = "disconnected";
})(PluginState || (PluginState = {}));
var DiscordRPCSettingsTab = /** @class */ (function (_super) {
__extends(DiscordRPCSettingsTab, _super);
function DiscordRPCSettingsTab() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.logger = new Logger();
return _this;
}
DiscordRPCSettingsTab.prototype.display = function () {
var _this = this;
var containerEl = this.containerEl;
var plugin = this.plugin;
containerEl.empty();
containerEl.createEl("h2", { text: "Discord Rich Presence Settings" });
containerEl.createEl("h3", { text: "Vault Name Settings" });
new obsidian.Setting(containerEl)
.setName("Show Vault Name")
.setDesc("Enable this to show the name of the vault you are working with.")
.addToggle(function (boolean) {
return boolean.setValue(plugin.settings.showVaultName).onChange(function (value) {
plugin.settings.showVaultName = value;
plugin.saveData(plugin.settings);
if (boolean.getValue()) {
_this.logger.logIgnoreNoNotice("Vault Name is now Visable");
}
else {
_this.logger.logIgnoreNoNotice("Vault Name is no longer Visable");
}
plugin.setActivity(_this.app.vault.getName(), plugin.currentFile.basename, plugin.currentFile.extension);
});
});
new obsidian.Setting(containerEl)
.setName("Set Custom Vault Name")
.setDesc("Change the vault name shown publicly. Leave blank to use your actual vault name.")
.addText(function (text) {
return text.setValue(plugin.settings.customVaultName).onChange(function (value) {
plugin.settings.customVaultName = value;
plugin.saveData(plugin.settings);
plugin.setActivity(_this.app.vault.getName(), plugin.currentFile.basename, plugin.currentFile.extension);
});
});
containerEl.createEl("h3", { text: "File Name Settings" });
new obsidian.Setting(containerEl)
.setName("Show Current File Name")
.setDesc("Enable this to show the name of the file you are working on.")
.addToggle(function (boolean) {
return boolean
.setValue(plugin.settings.showCurrentFileName)
.onChange(function (value) {
plugin.settings.showCurrentFileName = value;
plugin.saveData(plugin.settings);
if (boolean.getValue()) {
_this.logger.logIgnoreNoNotice("File Name is now Visable");
}
else {
_this.logger.logIgnoreNoNotice("File Name is no longer Visable");
}
plugin.setActivity(_this.app.vault.getName(), plugin.currentFile.basename, plugin.currentFile.extension);
});
});
new obsidian.Setting(containerEl)
.setName("Show File Extension")
.setDesc("Enable this to show file extension.")
.addToggle(function (boolean) {
return boolean
.setValue(plugin.settings.showFileExtension)
.onChange(function (value) {
plugin.settings.showFileExtension = value;
plugin.saveData(plugin.settings);
plugin.setActivity(_this.app.vault.getName(), plugin.currentFile.basename, plugin.currentFile.extension);
});
});
containerEl.createEl("h3", { text: "Time Settings" });
new obsidian.Setting(containerEl)
.setName("Use Obsidian Total Time")
.setDesc("Enable to use the total time you have been using Obsidian, instead of the time spent editing a single file.")
.addToggle(function (boolean) {
boolean.setValue(plugin.settings.useLoadedTime).onChange(function (value) {
plugin.settings.useLoadedTime = value;
plugin.saveData(plugin.settings);
plugin.setActivity(_this.app.vault.getName(), plugin.currentFile.basename, plugin.currentFile.extension);
});
});
containerEl.createEl("h3", { text: "Status Bar Settings" });
new obsidian.Setting(containerEl)
.setName("Automatically hide Status Bar")
.setDesc("Automatically hide status bar after successfully connecting to Discord.")
.addToggle(function (boolean) {
boolean.setValue(plugin.settings.autoHideStatusBar).onChange(function (value) {
plugin.settings.autoHideStatusBar = value;
plugin.saveData(plugin.settings);
plugin.setActivity(_this.app.vault.getName(), plugin.currentFile.basename, plugin.currentFile.extension);
});
});
containerEl.createEl("h3", { text: "Startup Settings" });
new obsidian.Setting(containerEl)
.setName("Automatically Connect to Discord")
.setDesc("Automatically connect to Discord on startup. You can always click the status bar to manually connect.")
.addToggle(function (boolean) {
boolean.setValue(plugin.settings.connectOnStart).onChange(function (value) {
plugin.settings.connectOnStart = value;
plugin.saveData(plugin.settings);
plugin.setActivity(_this.app.vault.getName(), plugin.currentFile.basename, plugin.currentFile.extension);
});
});
containerEl.createEl("h3", { text: "Notice Settings" });
new obsidian.Setting(containerEl)
.setName("Show Notices")
.setDesc("Enable this to show connection Notices.")
.addToggle(function (boolean) {
return boolean.setValue(plugin.settings.showPopups).onChange(function (value) {
plugin.settings.showPopups = value;
plugin.saveData(plugin.settings);
if (boolean.getValue()) {
_this.logger.logIgnoreNoNotice("Notices Enabled");
}
else {
_this.logger.logIgnoreNoNotice("Notices Disabled");
}
plugin.setActivity(_this.app.vault.getName(), plugin.currentFile.basename, plugin.currentFile.extension);
});
});
};
return DiscordRPCSettingsTab;
}(obsidian.PluginSettingTab));
var StatusBar = /** @class */ (function () {
function StatusBar(statusBarEl) {
this.statusBarEl = statusBarEl;
}
StatusBar.prototype.displayState = function (state, autoHide) {
switch (state) {
case PluginState.connected:
this.displayConnected(autoHide ? 10000 : 0);
break;
case PluginState.connecting:
this.statusBarEl.setText("Connecting to Discord...");
break;
case PluginState.disconnected:
this.statusBarEl.setText("\uD83D\uDDD8 Reconnect to Discord");
break;
}
};
StatusBar.prototype.displayConnected = function (timeout) {
var _this = this;
this.statusBarEl.setText("\uD83C\uDF0D Connected to Discord");
if (timeout && timeout > 0) {
window.setTimeout(function () {
_this.statusBarEl.setText("");
}, timeout);
}
else {
window.setTimeout(function () {
_this.statusBarEl.setText("\uD83C\uDF0D");
}, 5000);
}
};
return StatusBar;
}());
var ObsidianDiscordRPC = /** @class */ (function (_super) {
__extends(ObsidianDiscordRPC, _super);
function ObsidianDiscordRPC() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.logger = new Logger();
return _this;
}
ObsidianDiscordRPC.prototype.setState = function (state) {
this.state = state;
};
ObsidianDiscordRPC.prototype.getState = function () {
return this.state;
};
ObsidianDiscordRPC.prototype.getApp = function () {
return this.app;
};
ObsidianDiscordRPC.prototype.getPluginManifest = function () {
return this.manifest;
};
ObsidianDiscordRPC.prototype.onload = function () {
return __awaiter(this, void 0, void 0, function () {
var statusBarEl, _a, activeLeaf_1, files;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
statusBarEl = this.addStatusBarItem();
this.statusBar = new StatusBar(statusBarEl);
_a = this;
return [4 /*yield*/, this.loadData()];
case 1:
_a.settings = (_b.sent()) || new DiscordRPCSettings();
this.registerEvent(this.app.workspace.on("file-open", this.onFileOpen, this));
this.registerDomEvent(statusBarEl, "click", function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this.getState() == PluginState.disconnected)) return [3 /*break*/, 2];
return [4 /*yield*/, this.connectDiscord()];
case 1:
_a.sent();
return [3 /*break*/, 4];
case 2:
if (!(this.getState() == PluginState.connected)) return [3 /*break*/, 4];
return [4 /*yield*/, this.disconnectDiscord()];
case 3:
_a.sent();
_a.label = 4;
case 4: return [2 /*return*/];
}
});
}); });
this.addSettingTab(new DiscordRPCSettingsTab(this.app, this));
this.addCommand({
id: "reconnect-discord",
name: "Reconnect to Discord",
callback: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.connectDiscord()];
case 1: return [2 /*return*/, _a.sent()];
}
}); }); },
});
this.addCommand({
id: "disconnect-discord",
name: "Disconnect from Discord",
callback: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.disconnectDiscord()];
case 1: return [2 /*return*/, _a.sent()];
}
}); }); },
});
if (!this.settings.connectOnStart) return [3 /*break*/, 3];
return [4 /*yield*/, this.connectDiscord()];
case 2:
_b.sent();
activeLeaf_1 = this.app.workspace.activeLeaf;
files = this.app.vault.getMarkdownFiles();
files.forEach(function (file) {
if (file.basename === activeLeaf_1.getDisplayText()) {
_this.onFileOpen(file);
}
});
return [3 /*break*/, 4];
case 3:
this.setState(PluginState.disconnected);
this.statusBar.displayState(this.getState(), this.settings.autoHideStatusBar);
_b.label = 4;
case 4: return [2 /*return*/];
}
});
});
};
ObsidianDiscordRPC.prototype.onFileOpen = function (file) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.currentFile = file;
if (!(this.getState() === PluginState.connected)) return [3 /*break*/, 2];
return [4 /*yield*/, this.setActivity(this.app.vault.getName(), file.basename, file.extension)];
case 1:
_a.sent();
_a.label = 2;
case 2: return [2 /*return*/];
}
});
});
};
ObsidianDiscordRPC.prototype.onunload = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.saveData(this.settings)];
case 1:
_a.sent();
this.rpc.clearActivity();
this.rpc.destroy();
return [2 /*return*/];
}
});
});
};
ObsidianDiscordRPC.prototype.connectDiscord = function () {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.loadedTime = new Date();
this.rpc = new src.Client({
transport: "ipc",
});
this.setState(PluginState.connecting);
this.statusBar.displayState(this.getState(), this.settings.autoHideStatusBar);
this.rpc.once("ready", function () {
_this.setState(PluginState.connected);
_this.statusBar.displayState(_this.getState(), _this.settings.autoHideStatusBar);
_this.logger.log("Connected to Discord", _this.settings.showPopups);
});
_a.label = 1;
case 1:
_a.trys.push([1, 4, , 5]);
return [4 /*yield*/, this.rpc.login({
clientId: "763813185022197831",
})];
case 2:
_a.sent();
return [4 /*yield*/, this.setActivity(this.app.vault.getName(), "...", "")];
case 3:
_a.sent();
return [3 /*break*/, 5];
case 4:
_a.sent();
this.setState(PluginState.disconnected);
this.statusBar.displayState(this.getState(), this.settings.autoHideStatusBar);
this.logger.log("Failed to connect to Discord", this.settings.showPopups);
return [3 /*break*/, 5];
case 5: return [2 /*return*/];
}
});
});
};
ObsidianDiscordRPC.prototype.disconnectDiscord = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
this.rpc.clearActivity();
this.rpc.destroy();
this.setState(PluginState.disconnected);
this.statusBar.displayState(this.getState(), this.settings.autoHideStatusBar);
this.logger.log("Disconnected from Discord", this.settings.showPopups);
return [2 /*return*/];
});
});
};
ObsidianDiscordRPC.prototype.setActivity = function (vaultName, fileName, fileExtension) {
return __awaiter(this, void 0, void 0, function () {
var vault, file, date;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this.getState() === PluginState.connected)) return [3 /*break*/, 8];
vault = void 0;
if (this.settings.customVaultName === "") {
vault = vaultName;
}
else {
vault = this.settings.customVaultName;
}
file = void 0;
if (this.settings.showFileExtension) {
file = fileName + "." + fileExtension;
}
else {
file = fileName;
}
date = void 0;
if (this.settings.useLoadedTime) {
date = this.loadedTime;
}
else {
date = new Date();
}
if (!(this.settings.showVaultName && this.settings.showCurrentFileName)) return [3 /*break*/, 2];
return [4 /*yield*/, this.rpc.setActivity({
details: "Editing " + file,
state: "Vault: " + vault,
startTimestamp: date,
largeImageKey: "logo",
largeImageText: "Obsidian",
})];
case 1:
_a.sent();
return [3 /*break*/, 8];
case 2:
if (!this.settings.showVaultName) return [3 /*break*/, 4];
return [4 /*yield*/, this.rpc.setActivity({
state: "Vault: " + vault,
startTimestamp: date,
largeImageKey: "logo",
largeImageText: "Obsidian",
})];
case 3:
_a.sent();
return [3 /*break*/, 8];
case 4:
if (!this.settings.showCurrentFileName) return [3 /*break*/, 6];
return [4 /*yield*/, this.rpc.setActivity({
details: "Editing " + file,
startTimestamp: date,
largeImageKey: "logo",
largeImageText: "Obsidian",
})];
case 5:
_a.sent();
return [3 /*break*/, 8];
case 6: return [4 /*yield*/, this.rpc.setActivity({
startTimestamp: date,
largeImageKey: "logo",
largeImageText: "Obsidian",
})];
case 7:
_a.sent();
_a.label = 8;
case 8: return [2 /*return*/];
}
});
});
};
return ObsidianDiscordRPC;
}(obsidian.Plugin));
module.exports = ObsidianDiscordRPC;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsiLi4vbm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIi4uL25vZGVfbW9kdWxlcy9kaXNjb3JkLXJwYy9zcmMvdXRpbC5qcyIsIi4uL25vZGVfbW9kdWxlcy9ub2RlLWZldGNoL2Jyb3dzZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvZGlzY29yZC1ycGMvc3JjL3RyYW5zcG9ydHMvaXBjLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2Rpc2NvcmQtcnBjL3NyYy9jb25zdGFudHMuanMiLCIuLi9ub2RlX21vZHVsZXMvZGlzY29yZC1ycGMvc3JjL3RyYW5zcG9ydHMvd2Vic29ja2V0LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2Rpc2NvcmQtcnBjL3NyYy90cmFuc3BvcnRzL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2Rpc2NvcmQtcnBjL3NyYy9jbGllbnQuanMiLCIuLi9ub2RlX21vZHVsZXMvZGlzY29yZC1ycGMvc3JjL2luZGV4LmpzIiwiLi4vc3JjL2xvZ2dlci50cyIsIi4uL3NyYy9zZXR0aW5ncy9zZXR0aW5ncy50cyIsIi4uL3NyYy9zZXR0aW5ncy9zZXR0aW5ncy10YWIudHMiLCIuLi9zcmMvc3RhdHVzLWJhci50cyIsIi4uL3NyYy9tYWluLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICA