mirror of
https://github.com/smartfrigde/armcord.git
synced 2024-08-14 23:56:58 +00:00
Initial source code upload
This commit is contained in:
parent
3fd237446f
commit
101bc63651
41 changed files with 1117 additions and 6272 deletions
85
src/content/css/setup.css
Normal file
85
src/content/css/setup.css
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*CSS ONLY FOR INTERNAL USE (setup and loading)*/
|
||||
@import url("https://kckarnige.github.io/femboi_owo/discord-font.css");
|
||||
|
||||
:root {
|
||||
background-color: #2c2f33;
|
||||
--header-secondary: #b9bbbe;
|
||||
--header-primary: #fff;
|
||||
--background-tertiary: #202225;
|
||||
}
|
||||
|
||||
body {
|
||||
color: white;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #8e9297;
|
||||
text-align: center;
|
||||
font-weight: 100;
|
||||
transform: translateY(-185%);
|
||||
font-family: Whitney, Helvetica Neue, Helvetica, Arial, sans-serif;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 0px;
|
||||
text-align: center;
|
||||
transform: translateY(-105%);
|
||||
}
|
||||
|
||||
.logo:before {
|
||||
content: "ARM";
|
||||
color: #7289da;
|
||||
font-weight: normal;
|
||||
font-family: Helvetica, sans-serif;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.logo:after {
|
||||
content: "Cord";
|
||||
color: #ffffff;
|
||||
font-weight: normal;
|
||||
font-family: Discordinated;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
span {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-height: 204px;
|
||||
max-width: 204px;
|
||||
transform: translateY(5%);
|
||||
}
|
||||
|
||||
.container {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
color: #fff;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #7289da;
|
||||
font-family: Whitney, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
color: #ffffff;
|
||||
padding: 4px;
|
||||
border-radius: 5px;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
border-style: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #687dc6;
|
||||
border-style: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
114
src/content/css/splash.css
Normal file
114
src/content/css/splash.css
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*MIT License
|
||||
|
||||
Copyright (c) 2021 GooseMod
|
||||
|
||||
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.*/
|
||||
:root {
|
||||
--background-primary: #282b30;
|
||||
--background-secondary: rgba(255, 255, 255, 0.1);
|
||||
--brand-experiment: #5865f2;
|
||||
--header-primary: #fff;
|
||||
--text-muted: #72767d;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Whitney;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
src: url(https://armcord.smartfridge.space/whitney_400.woff) format("woff");
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
-webkit-app-region: drag;
|
||||
overflow: hidden;
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background: var(--background-primary);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "Whitney", sans-serif;
|
||||
|
||||
box-sizing: border-box;
|
||||
-webkit-user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
video {
|
||||
width: 200px;
|
||||
height: 150px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
#text {
|
||||
font-size: 7vw;
|
||||
text-align: center;
|
||||
|
||||
color: var(--header-primary);
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
font-size: 16px;
|
||||
|
||||
text-transform: uppercase;
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#bar-container,
|
||||
#bar-fill {
|
||||
width: 180px;
|
||||
height: 8px;
|
||||
|
||||
border-radius: 4px;
|
||||
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#bar-container {
|
||||
background-color: var(--background-secondary);
|
||||
|
||||
position: relative;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
#bar-fill {
|
||||
background-color: var(--brand-experiment);
|
||||
width: 0;
|
||||
}
|
||||
|
||||
#debug {
|
||||
position: absolute;
|
||||
bottom: 6px;
|
||||
right: 6px;
|
||||
|
||||
text-align: right;
|
||||
font-size: 10px;
|
||||
color: var(--text-muted);
|
||||
white-space: pre;
|
||||
}
|
123
src/content/css/titlebar.css
Normal file
123
src/content/css/titlebar.css
Normal file
|
@ -0,0 +1,123 @@
|
|||
@import url("https://kckarnige.github.io/femboi_owo/discord-font.css");
|
||||
:root {
|
||||
--window-buttons: var(--header-secondary);
|
||||
--cord-color: var(--header-primary);
|
||||
--armcord-color: #7289da;
|
||||
--titlebar-color: var(--background-tertiary);
|
||||
}
|
||||
.titleebar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
font-size: 13px;
|
||||
padding: 0 16px;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
user-select: none;
|
||||
zoom: 1;
|
||||
line-height: 22px;
|
||||
height: 22px;
|
||||
display: flex;
|
||||
z-index: 99999;
|
||||
}
|
||||
.titlebar {
|
||||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
zoom: 1;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
clear:both;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
background-color: #202225;
|
||||
-webkit-app-region: drag;
|
||||
width: 100%;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
position: fixed;
|
||||
z-index: 99999;
|
||||
|
||||
}
|
||||
.appMount-3lHmkl{
|
||||
|
||||
}
|
||||
.titlebar #window-title {
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
line-height: 30px;
|
||||
float: left;
|
||||
padding: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.titlebar #window-controls-container {
|
||||
float: right;
|
||||
width: 150px;
|
||||
height: 100%;
|
||||
line-height: 30px;
|
||||
background-color: #202225;
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.titlebar #window-controls-container #minimize,
|
||||
.titlebar #window-controls-container #maximize,
|
||||
.titlebar #window-controls-container #quit {
|
||||
float: left;
|
||||
height: 100%;
|
||||
width: 33%;
|
||||
text-align: center;
|
||||
color: #f7f7f7;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.titlebar #window-controls-container #minimize:hover {
|
||||
background-color: #99AAB5;
|
||||
}
|
||||
.titlebar #window-controls-container #maximize:hover {
|
||||
background-color: #99AAB5;
|
||||
}
|
||||
.titlebar #window-controls-container #quit:hover {
|
||||
background-color: #F04747;
|
||||
}
|
||||
.titlebar #window-controls-container #quit {
|
||||
background-color: #f7f7f7;
|
||||
-webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%;
|
||||
mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%;
|
||||
}
|
||||
.titlebar #window-controls-container #minimize {
|
||||
background-color: #f7f7f7;
|
||||
-webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 4.399V5.5H0V4.399h11z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%;
|
||||
mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 4.399V5.5H0V4.399h11z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%;
|
||||
}
|
||||
.titlebar #window-controls-container #maximize {
|
||||
background-color: #f7f7f7;
|
||||
-webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%;
|
||||
mask: url("data:image/svg+xml;charset=utf-8,%3Csvg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z' fill='%23000'/%3E%3C/svg%3E") no-repeat 50% 50%;
|
||||
}
|
||||
.window-title:after {
|
||||
content: "Cord";
|
||||
color: var(--cord-color) !important;
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
font-family: Discordinated;
|
||||
}
|
||||
.window-title:before {
|
||||
content: "ARM";
|
||||
color: var(--armcord-color);
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
font-family: Helvetica, sans-serif;
|
||||
}
|
||||
.window-title {
|
||||
font-size: 0px !important;
|
||||
margin-left: initial !important;
|
||||
transform: translate(10px, 0px);
|
||||
}
|
50
src/content/index.html
Normal file
50
src/content/index.html
Normal file
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ArmCord</title>
|
||||
<style>
|
||||
@import url("css/splash.css");
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<video autoplay loop class="logo">
|
||||
<source
|
||||
src="https://armcord.smartfridge.space/discord_loading.webm"
|
||||
type="video/webm"
|
||||
/>
|
||||
</video>
|
||||
<p id="text"></p>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
const text = document.getElementById("text");
|
||||
if (window.navigator.onLine === false) {
|
||||
text.innerHTML =
|
||||
"You appear to be offline. Please connect to the internet and try again.";
|
||||
} else {
|
||||
text.innerHTML = "Starting ArmCord...";
|
||||
|
||||
setTimeout(() => {
|
||||
window.armcord.splashEnd();
|
||||
switch (window.armcord.channel) {
|
||||
case "stable":
|
||||
window.location.href = "https://discord.com/app";
|
||||
break;
|
||||
case "canary":
|
||||
window.location.href = "https://canary.discord.com/app";
|
||||
break;
|
||||
case "ptb":
|
||||
window.location.href = "https://ptb.discord.com/app";
|
||||
break;
|
||||
case "foss":
|
||||
window.location.href = "https://dev.fosscord.com/app";
|
||||
break;
|
||||
default:
|
||||
window.location.href = "https://discord.com/app";
|
||||
}}, 5000);
|
||||
}
|
||||
</script>
|
||||
</html>
|
24
src/content/setup.html
Normal file
24
src/content/setup.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>ArmCord Setup</title>
|
||||
<style>
|
||||
@import url("css/setup.css");
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="logo"></h1>
|
||||
<h2>Welcome to ArmCord!</h2>
|
||||
<p>Select what kind of setup you want to perform:</p>
|
||||
<button id="express">Express setup</button>
|
||||
<button id="full">Full setup</button>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
26
src/extensions/plugin.ts
Normal file
26
src/extensions/plugin.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import * as fs from 'fs';
|
||||
import { app, session } from 'electron';
|
||||
const userDataPath = app.getPath("userData");
|
||||
const pluginFolder = userDataPath + "/plugins/";
|
||||
if (!fs.existsSync(pluginFolder)) {
|
||||
fs.mkdirSync(pluginFolder);
|
||||
console.log("Created missing plugin folder");
|
||||
}
|
||||
app.whenReady().then(() => {
|
||||
fs.readdirSync(pluginFolder).forEach((file) => {
|
||||
try {
|
||||
const manifest = fs.readFileSync(
|
||||
`${userDataPath}/plugins/${file}/manifest.json`,
|
||||
"utf8"
|
||||
);
|
||||
var pluginFile = JSON.parse(manifest);
|
||||
session.defaultSession.loadExtension(`${userDataPath}/plugins/${file}`);
|
||||
console.log(
|
||||
`%cLoaded ${pluginFile.name} made by ${pluginFile.author}`,
|
||||
"color:red"
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
});
|
0
src/extensions/themes.ts
Normal file
0
src/extensions/themes.ts
Normal file
92
src/main.ts
Normal file
92
src/main.ts
Normal file
|
@ -0,0 +1,92 @@
|
|||
// Modules to control application life and create native browser window
|
||||
import { app, BrowserWindow, ipcMain, shell } from "electron";
|
||||
import * as path from "path";
|
||||
import * as storage from 'electron-json-storage';
|
||||
import {setup} from './utils';
|
||||
import './extensions/plugin';
|
||||
var isSetup = null;
|
||||
var contentPath:string = "null";
|
||||
var frame:boolean;
|
||||
|
||||
storage.keys(function(error, keys) {
|
||||
if (error) throw error;
|
||||
|
||||
for (var key of keys) {
|
||||
console.log('There is a key called: ' + key);
|
||||
}
|
||||
});
|
||||
storage.has('firstRun', function(error, hasKey) {
|
||||
if (error) throw error;
|
||||
|
||||
if (!hasKey) {
|
||||
console.log('First run of the ArmCord. Starting setup.');
|
||||
isSetup = true;
|
||||
setup();
|
||||
contentPath = __dirname + '/content/setup.html'
|
||||
} else {
|
||||
console.log('ArmCord has been run before. Skipping setup.');
|
||||
isSetup = false;
|
||||
contentPath = __dirname + '/content/index.html'
|
||||
}
|
||||
});
|
||||
storage.get('settings', function(error, data:any) {
|
||||
if (error) throw error;
|
||||
console.log(data);
|
||||
frame = data.customTitlebar;
|
||||
console.log(frame)
|
||||
});
|
||||
function createWindow () {
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 300,
|
||||
height: 300,
|
||||
title: "ArmCord",
|
||||
frame: frame,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload/preload.js')
|
||||
}
|
||||
})
|
||||
ipcMain.on("get-app-path", (event, arg) => {
|
||||
event.reply("app-path", app.getAppPath());
|
||||
});
|
||||
ipcMain.on("open-external-link", (event, href: string) => {
|
||||
shell.openExternal(href);
|
||||
});
|
||||
ipcMain.on("win-maximize", (event, arg) => {
|
||||
mainWindow.maximize();
|
||||
});
|
||||
ipcMain.on("win-isMaximized", (event, arg) => {
|
||||
event.returnValue = mainWindow.isMaximized();
|
||||
});
|
||||
ipcMain.on("win-minimize", (event, arg) => {
|
||||
mainWindow.minimize();
|
||||
});
|
||||
ipcMain.on("win-show", (event, arg) => {
|
||||
mainWindow.show();
|
||||
});
|
||||
ipcMain.on("win-hide", (event, arg) => {
|
||||
mainWindow.hide();
|
||||
});
|
||||
ipcMain.on("get-app-version", (event) => {
|
||||
event.returnValue = process.env.npm_package_version;
|
||||
})
|
||||
ipcMain.on("splashEnd", (event, arg) => {
|
||||
mainWindow.setSize(800, 600);
|
||||
});
|
||||
ipcMain.on("channel", (event) => {
|
||||
event.returnValue = storage.getSync('channel');
|
||||
})
|
||||
mainWindow.loadFile(contentPath)
|
||||
}
|
||||
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
|
||||
app.on('activate', function () {
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
})
|
||||
})
|
||||
|
||||
app.on('window-all-closed', function () {
|
||||
if (process.platform !== 'darwin') app.quit()
|
||||
})
|
17
src/preload/bridge.ts
Normal file
17
src/preload/bridge.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
import { contextBridge, ipcRenderer } from 'electron';
|
||||
import {getDisplayMediaSelector} from './capturer';
|
||||
|
||||
contextBridge.exposeInMainWorld("armcord", {
|
||||
window: {
|
||||
show: () => ipcRenderer.sendSync('win-show'),
|
||||
hide: () => ipcRenderer.sendSync('win-hide'),
|
||||
minimize: () => ipcRenderer.sendSync('win-minimize'),
|
||||
maximize: () => ipcRenderer.sendSync('win-maximize'),
|
||||
},
|
||||
electron: process.versions.electron,
|
||||
version: ipcRenderer.sendSync('get-app-version', 'app-version'),
|
||||
getDisplayMediaSelector: getDisplayMediaSelector,
|
||||
splashEnd: () => ipcRenderer.sendSync('splashEnd'),
|
||||
channel: ipcRenderer.sendSync('channel')
|
||||
});
|
152
src/preload/capturer.ts
Normal file
152
src/preload/capturer.ts
Normal file
|
@ -0,0 +1,152 @@
|
|||
//Fixed context isolation version https://github.com/getferdi/ferdi/blob/develop/src/webview/screenshare.ts
|
||||
//original https://github.com/electron/electron/issues/16513#issuecomment-602070250
|
||||
import { desktopCapturer } from 'electron';
|
||||
import {addStyle, addScript} from '../utils';
|
||||
|
||||
const CANCEL_ID = 'desktop-capturer-selection__cancel';
|
||||
|
||||
export async function getDisplayMediaSelector() {
|
||||
const sources = await desktopCapturer.getSources({
|
||||
types: ['screen', 'window'],
|
||||
});
|
||||
return `<div class="desktop-capturer-selection__scroller">
|
||||
<ul class="desktop-capturer-selection__list">
|
||||
${sources
|
||||
.map(
|
||||
({ id, name, thumbnail }) => `
|
||||
<li class="desktop-capturer-selection__item">
|
||||
<button class="desktop-capturer-selection__btn" data-id="${id}" title="${name}">
|
||||
<img class="desktop-capturer-selection__thumbnail" src="${thumbnail.toDataURL()}" />
|
||||
<span class="desktop-capturer-selection__name">${name}</span>
|
||||
</button>
|
||||
</li>
|
||||
`,
|
||||
)
|
||||
.join('')}
|
||||
<li class="desktop-capturer-selection__item">
|
||||
<button class="desktop-capturer-selection__btn" data-id="${CANCEL_ID}" title="Cancel">
|
||||
<span class="desktop-capturer-selection__name desktop-capturer-selection__name--cancel">Cancel</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
const screenShareCSS = `
|
||||
.desktop-capturer-selection {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background: rgba(30,30,30,.75);
|
||||
color: #FFFFFF;
|
||||
z-index: 10000000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.desktop-capturer-selection__scroller {
|
||||
width: 100%;
|
||||
max-height: 100vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.desktop-capturer-selection__list {
|
||||
max-width: calc(100% - 100px);
|
||||
margin: 50px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
list-style: none;
|
||||
overflow: hidden;
|
||||
justify-content: center;
|
||||
}
|
||||
.desktop-capturer-selection__item {
|
||||
display: flex;
|
||||
margin: 4px;
|
||||
}
|
||||
.desktop-capturer-selection__btn {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
width: 145px;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
padding: 4px;
|
||||
background: #2C2F33;
|
||||
text-align: left;
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
transition: background-color .15s, box-shadow .15s, color .15s;
|
||||
}
|
||||
color: #dedede;
|
||||
}
|
||||
.desktop-capturer-selection__btn:hover,
|
||||
.desktop-capturer-selection__btn:focus {
|
||||
background: #7289DA;
|
||||
box-shadow: 0 0 4px rgba(0,0,0,0.45), 0 0 2px rgba(0,0,0,0.25);
|
||||
color: #fff;
|
||||
}
|
||||
.desktop-capturer-selection__thumbnail {
|
||||
width: 100%;
|
||||
height: 81px;
|
||||
object-fit: cover;
|
||||
}
|
||||
.desktop-capturer-selection__name {
|
||||
margin: 6px 0;
|
||||
white-space: nowrap;
|
||||
color: white;
|
||||
text-overflow: ellipsis;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
.desktop-capturer-selection__name--cancel {
|
||||
margin: auto 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const screenShareJS = `
|
||||
window.navigator.mediaDevices.getDisplayMedia = () => new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const selectionElem = document.createElement('div');
|
||||
selectionElem.classList = ['desktop-capturer-selection'];
|
||||
selectionElem.innerHTML = await window.electron.getDisplayMediaSelector();
|
||||
document.body.appendChild(selectionElem);
|
||||
document
|
||||
.querySelectorAll('.desktop-capturer-selection__btn')
|
||||
.forEach((button) => {
|
||||
button.addEventListener('click', async () => {
|
||||
try {
|
||||
const id = button.getAttribute('data-id');
|
||||
if (id === '${CANCEL_ID}') {
|
||||
reject(new Error('Cancelled by user'));
|
||||
} else {
|
||||
const stream = await window.navigator.mediaDevices.getUserMedia({
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop',
|
||||
chromeMediaSourceId: id,
|
||||
},
|
||||
},
|
||||
});
|
||||
resolve(stream);
|
||||
}
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
} finally {
|
||||
selectionElem.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
`;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
addScript(screenShareJS);
|
||||
addStyle(screenShareCSS);
|
||||
});
|
||||
|
5
src/preload/preload.ts
Normal file
5
src/preload/preload.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import './capturer'
|
||||
import './bridge'
|
||||
import {injectTitlebar} from './titlebar';
|
||||
injectTitlebar();
|
||||
console.log("ArmCord");
|
46
src/preload/titlebar.ts
Normal file
46
src/preload/titlebar.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
import { ipcRenderer } from 'electron';
|
||||
import {addStyle} from '../utils'
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
export function injectTitlebar() {
|
||||
document.addEventListener("DOMContentLoaded", function (event) {
|
||||
var elem = document.createElement("div");
|
||||
elem.innerHTML = `<nav class="titlebar">
|
||||
<div class="window-title" id="window-title"></div>
|
||||
<div id="window-controls-container">
|
||||
<div id="minimize"></div>
|
||||
<div id="maximize"></div>
|
||||
<div id="quit"></div>
|
||||
</div>
|
||||
</nav>`;
|
||||
document.body.appendChild(elem);
|
||||
const cssPath = path.join(__dirname, '../', '/content/css/titlebar.css');
|
||||
addStyle(fs.readFileSync(
|
||||
cssPath,
|
||||
"utf8"
|
||||
));
|
||||
|
||||
var minimize = document.querySelector("#minimize");
|
||||
var maximize = document.querySelector("#maximize");
|
||||
var quit = document.querySelector("#quit");
|
||||
|
||||
minimize!.addEventListener("click", () => {
|
||||
ipcRenderer.sendSync('win-minimize')
|
||||
});
|
||||
|
||||
maximize!.addEventListener("click", () => {
|
||||
if (ipcRenderer.sendSync('win-isMaximized') == true) {
|
||||
ipcRenderer.sendSync('win-minimize')
|
||||
} else {
|
||||
ipcRenderer.sendSync('win-maximize')
|
||||
}
|
||||
});
|
||||
|
||||
quit!.addEventListener("click", () => {
|
||||
ipcRenderer.sendSync('win-hide')
|
||||
});
|
||||
});
|
||||
}
|
||||
export function removeTitlebar() {
|
||||
document.querySelector('#titlebar')!.remove();
|
||||
}
|
24
src/utils.ts
Normal file
24
src/utils.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import * as storage from 'electron-json-storage';
|
||||
//utillity functions that are used all over the codebase or just too obscure to be put in the file used in
|
||||
export function addStyle(styleString: string) {
|
||||
const style = document.createElement('style');
|
||||
style.textContent = styleString;
|
||||
document.head.append(style);
|
||||
};
|
||||
|
||||
export function addScript(scriptString: string) {
|
||||
var script = document.createElement("script");
|
||||
script.textContent = scriptString;
|
||||
document.body.append(script);
|
||||
};
|
||||
export function setup(){
|
||||
console.log("Setting up ArmCord settings.");
|
||||
storage.set('settings', { customTitlebar: true, channel: 'stable', firstRun: 'done' }, function(error) {
|
||||
if (error) throw error;
|
||||
});
|
||||
}
|
||||
export interface settingsStructure {
|
||||
channel: string,
|
||||
customTitlebar: boolean,
|
||||
firstRun: string,
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue