aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--all.json2
-rw-r--r--recipes/discord/package.json2
-rw-r--r--recipes/discord/webview.js116
3 files changed, 103 insertions, 17 deletions
diff --git a/all.json b/all.json
index aa9b8ab..d0d56c8 100644
--- a/all.json
+++ b/all.json
@@ -219,7 +219,7 @@
219 "featured": true, 219 "featured": true,
220 "id": "discord", 220 "id": "discord",
221 "name": "Discord", 221 "name": "Discord",
222 "version": "1.1.5", 222 "version": "1.2.0",
223 "icons": { 223 "icons": {
224 "svg": "https://cdn.jsdelivr.net/gh/getferdi/recipes/recipes/discord/icon.svg" 224 "svg": "https://cdn.jsdelivr.net/gh/getferdi/recipes/recipes/discord/icon.svg"
225 } 225 }
diff --git a/recipes/discord/package.json b/recipes/discord/package.json
index 42805cd..d713dfb 100644
--- a/recipes/discord/package.json
+++ b/recipes/discord/package.json
@@ -1,7 +1,7 @@
1{ 1{
2 "id": "discord", 2 "id": "discord",
3 "name": "Discord", 3 "name": "Discord",
4 "version": "1.1.5", 4 "version": "1.2.0",
5 "license": "MIT", 5 "license": "MIT",
6 "config": { 6 "config": {
7 "serviceURL": "https://discordapp.com/login", 7 "serviceURL": "https://discordapp.com/login",
diff --git a/recipes/discord/webview.js b/recipes/discord/webview.js
index 270ca0e..8123ced 100644
--- a/recipes/discord/webview.js
+++ b/recipes/discord/webview.js
@@ -1,28 +1,114 @@
1const _path = _interopRequireDefault(require('path')); 1"use strict";
2 2
3function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3// TODO: Some/most of this is already present in https://github.com/getferdi/ferdi/blob/develop/src/webview/screenshare.js#L5
4 4
5module.exports = Franz => { 5const { desktopCapturer, remote: { BrowserWindow } } = require("electron");
6const path = require('path');
7
8window.navigator.mediaDevices.getDisplayMedia = () => {
9 return new Promise(async (resolve, reject) => {
10 try {
11 const sources = await desktopCapturer.getSources({ types: ['screen', 'window'] });
12
13 const selectionElem = document.createElement('div');
14 selectionElem.classList = 'desktop-capturer-selection';
15 selectionElem.innerHTML = `
16 <div class="desktop-capturer-selection__scroller">
17 <ul class="desktop-capturer-selection__list">
18 ${sources.map(({ id, name, thumbnail, display_id, appIcon }) => `
19 <li class="desktop-capturer-selection__item">
20 <button class="desktop-capturer-selection__btn" data-id="${id}" title="${name}">
21 <img class="desktop-capturer-selection__thumbnail" src="${thumbnail.toDataURL()}" />
22 <span class="desktop-capturer-selection__name">${name}</span>
23 </button>
24 </li>
25 `).join('')}
26 </ul>
27 </div>
28 `;
29 document.body.appendChild(selectionElem);
30
31 document.querySelectorAll('.desktop-capturer-selection__btn')
32 .forEach(button => {
33 button.addEventListener('click', async () => {
34 try {
35 const id = button.getAttribute('data-id');
36 const source = sources.find(source => source.id === id);
37 if (!source) {
38 throw new Error(`Source with id ${id} does not exist`);
39 }
40
41 const stream = await window.navigator.mediaDevices.getUserMedia({
42 audio: false,
43 video: {
44 mandatory: {
45 chromeMediaSource: 'desktop',
46 chromeMediaSourceId: source.id
47 }
48 }
49 });
50 resolve(stream);
51
52 selectionElem.remove();
53 } catch (err) {
54 reject(err);
55 }
56 });
57 });
58 } catch (err) {
59 reject(err);
60 }
61 })
62}
63
64module.exports = (Franz, settings) => {
6 const getMessages = function getMessages() { 65 const getMessages = function getMessages() {
7 const direct = document.querySelector('[class*="guilds-"]').querySelectorAll('[class^="numberBadge-"]').length; 66 let count = 0;
67 const container = document.querySelector('[role="tablist"] > [title="Chats"] > div');
8 68
9 let indirect = 0; 69 if (container) {
10 const guilds = document.querySelector('[data-ref-id=guildsnav]'); 70 const children = container.children;
11 if (guilds != null) {
12 const channelPills = [].slice.call(guilds.querySelectorAll('[class*=item-2hkk8m]'));
13 indirect += channelPills.filter(y => y.clientHeight == 8).length;
14 71
15 const activeWindow = channelPills.find(y => y.clientHeight == 40); 72 if (children.length === 3) {
16 if (activeWindow != null) { 73 const elementContainer = children[children.length - 1];
17 const unreadChannels = document.querySelector('[class*=modeUnread]');
18 74
19 if (unreadChannels != null) indirect++; 75 if (elementContainer) {
76 const element = elementContainer.querySelector('[data-text-as-pseudo-element]');
77 count = parseInt(element.dataset.textAsPseudoElement, 10);
78 }
20 } 79 }
21 } 80 }
22 81
23 Franz.setBadge(direct, indirect); 82 Franz.setBadge(count);
24 }; 83 };
25 84
85 Franz.injectCSS(path.join(__dirname, 'service.css'));
26 Franz.loop(getMessages); 86 Franz.loop(getMessages);
27 Franz.injectCSS(_path.default.join(__dirname, 'service.css')); 87 document.addEventListener('click', event => {
88 const link = event.target.closest('a[href^="http"]');
89 const button = event.target.closest('button[title^="http"]');
90
91 if (link || button) {
92 const url = link ? link.getAttribute('href') : button.getAttribute('title');
93 event.preventDefault();
94 event.stopPropagation();
95
96 if (url.includes('views/imgpsh_fullsize_anim')) {
97 let win = new BrowserWindow({
98 width: 800,
99 height: window.innerHeight,
100 minWidth: 600,
101 webPreferences: {
102 partition: `persist:service-${settings.id}`
103 }
104 });
105 win.loadURL(url);
106 win.on('closed', () => {
107 win = null;
108 });
109 } else {
110 window.open(url);
111 }
112 }
113 }, true);
28}; 114};