Compare commits
91 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bec69b3abf | ||
|
|
530e82cc6d | ||
|
|
29765230b1 | ||
|
|
29a556c7d1 | ||
|
|
7f3d4ba8aa | ||
|
|
9c714c9c4e | ||
|
|
91ef9955b4 | ||
|
|
97f0f3784d | ||
|
|
42d903ac16 | ||
|
|
b9111348d3 | ||
|
|
69b7fa79de | ||
|
|
4c67233e83 | ||
|
|
c9d14992b9 | ||
|
|
f06411e018 | ||
|
|
73b9c419ff | ||
|
|
e763d98134 | ||
|
|
0533256b87 | ||
|
|
4d0c874a95 | ||
|
|
ae1608e0bb | ||
|
|
88ae7c8994 | ||
|
|
d697ce8c81 | ||
|
|
a684cf1294 | ||
|
|
b9d4028074 | ||
|
|
916cb7e76f | ||
|
|
6dd61af5dd | ||
|
|
5bee7c0791 | ||
|
|
a4a731f04a | ||
|
|
b15d3c5375 | ||
|
|
99ba73f194 | ||
|
|
1456c15f91 | ||
|
|
8a26580453 | ||
|
|
af393ad0ca | ||
|
|
8a46f3a7d2 | ||
|
|
0aff71496c | ||
|
|
f3a5642bcd | ||
|
|
b97e6e0870 | ||
|
|
3e704c3d22 | ||
|
|
ae02fa80ce | ||
|
|
ec5c1038b3 | ||
|
|
e5e6295a83 | ||
|
|
19560fe60f | ||
|
|
1f1b469a4b | ||
|
|
eb095a7497 | ||
|
|
6415b095ab | ||
|
|
d93c959da8 | ||
|
|
09893e1409 | ||
|
|
93ec6384d0 | ||
|
|
a221bf33b2 | ||
|
|
c7ec3d2197 | ||
|
|
18d04099fd | ||
|
|
fec52ee19f | ||
|
|
d87a22da23 | ||
|
|
4bda273947 | ||
|
|
7c8a2e32b4 | ||
|
|
45e8d0c2b6 | ||
|
|
3fe0b93567 | ||
|
|
06147dd5cc | ||
|
|
44dae3832e | ||
|
|
4f06d804e9 | ||
|
|
fb87b201da | ||
|
|
a58090b334 | ||
|
|
0050bfe36f | ||
|
|
d40233cb1e | ||
|
|
3125f8e7d1 | ||
|
|
0646fb77f2 | ||
|
|
c5a3a17a94 | ||
|
|
e4b1880025 | ||
|
|
c0b74c1605 | ||
|
|
96aed66af2 | ||
|
|
65e23a90a1 | ||
|
|
f3405b5724 | ||
|
|
5bef1e5663 | ||
|
|
5120cee05a | ||
|
|
895e593d02 | ||
|
|
32d8070119 | ||
|
|
46273ecbe5 | ||
|
|
4268099a06 | ||
|
|
921db2f6cb | ||
|
|
f640c45464 | ||
|
|
d4dc7a32a4 | ||
|
|
33e5171742 | ||
|
|
ebb4857782 | ||
|
|
c47d253967 | ||
|
|
c58e7d2ccf | ||
|
|
f3cad86f6f | ||
|
|
a23655de42 | ||
|
|
b7b899ea40 | ||
|
|
89029b1bc3 | ||
|
|
9b4212e00c | ||
|
|
6b158e1e23 | ||
|
|
6cae350ef2 |
6
.gitignore
vendored
@@ -1,4 +1,6 @@
|
||||
node_modules
|
||||
out
|
||||
.vscode
|
||||
dist
|
||||
dist
|
||||
website
|
||||
server
|
||||
.vscode
|
||||
104
Extension/_locales/de/messages.json
Normal file
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"appDesc": {
|
||||
"message": "PreMiD fügt eine Discord-Rich-Presence-Integration, Kontrolle über Multimediatasten und viele weitere Funktionen zu YouTube/YouTube Music, Twitch etc. hinzu."
|
||||
},
|
||||
"connected": {
|
||||
"message": "Verbunden"
|
||||
},
|
||||
"disconnected": {
|
||||
"message": "Getrennt"
|
||||
},
|
||||
"installedThanks": {
|
||||
"message": "Vielen Dank, für das Installieren von PreMiD"
|
||||
},
|
||||
"installedApp": {
|
||||
"message": "Hast du das Programm bereits installiert?"
|
||||
},
|
||||
"installedNo": {
|
||||
"message": "Nein? Folge dieser Anleitung:"
|
||||
},
|
||||
"installedStepApp": {
|
||||
"message": "Lade die neueste Version von $1 herunter"
|
||||
},
|
||||
"installedStepAppMyRepository": {
|
||||
"message": "meinem GitHub Repository"
|
||||
},
|
||||
"installedWaitInstalled": {
|
||||
"message": "Offne das Installationsprogramm und warte bis die Installation abgeschlossen ist"
|
||||
},
|
||||
"installedMayWarning": {
|
||||
"message": "Möglicherweise bekommst du eine Warnung von deiner FireWall und SmartScreen (Es ist kein Virus. Das verspreche ich dir!)"
|
||||
},
|
||||
"installedAppAutostart": {
|
||||
"message": "Das Programm sollte automatisch starten. Du kannst dies prüfen, indem du auf deine Taskbar (Windows) oder deine Menubar (MacOS) schaust"
|
||||
},
|
||||
"installedYes": {
|
||||
"message": "Ja? Jetzt bist du bereit!"
|
||||
},
|
||||
"installedStart": {
|
||||
"message": "Starte, indem du ein Video auf YouTube, deine Lieblingsstreamer auf Twitch, deine Lieblings Animes auf KissAnime oder JKAnime anschaust oder vielleicht sogar Netflix... Wer weiß?<br>Oder du hörst dir deine Lieblingslieder auf SoundCloud und YouTube Music an. Einstellungen findest du indem du auf das PreMiD icon in deinem Browser klickst."
|
||||
},
|
||||
"installedSupportMe": {
|
||||
"message": "Unterstütze mich!"
|
||||
},
|
||||
"updatedYTPUpdated": {
|
||||
"message": "PreMiD wurde aktualisiert!"
|
||||
},
|
||||
"updatedWhatsNew": {
|
||||
"message": "Was ist neu?"
|
||||
},
|
||||
"updatedWhatChanged": {
|
||||
"message": "Was hat sich geändert?"
|
||||
},
|
||||
"updatedAdded0": {
|
||||
"message": "Support für JKAnime & KissAnime"
|
||||
},
|
||||
"updatedAdded1": {
|
||||
"message": "Erweiterungs Popup"
|
||||
},
|
||||
"updatedChanged0": {
|
||||
"message": "Eine Menge und Ich meine eine Menge Neuschreibungen!"
|
||||
},
|
||||
"updatedChanged1": {
|
||||
"message": "Große Schnelligkeits Verbesserungen der App"
|
||||
},
|
||||
"updatedAdded2": {
|
||||
"message": "Einstellungs Synchronisation (Google Account)"
|
||||
},
|
||||
"playbackPlaying": {
|
||||
"message": "Wiedergabe"
|
||||
},
|
||||
"playbackPaused": {
|
||||
"message": "Wiedergabe pausiert"
|
||||
},
|
||||
"about": {
|
||||
"message": "Über"
|
||||
},
|
||||
"feedback": {
|
||||
"message": "Feedback"
|
||||
},
|
||||
"options": {
|
||||
"message": "Optionen"
|
||||
},
|
||||
"general": {
|
||||
"message": "Allgemein"
|
||||
},
|
||||
"enabled": {
|
||||
"message": "Eingeschaltet"
|
||||
},
|
||||
"titleMenubar": {
|
||||
"message": "Titel Menubar"
|
||||
},
|
||||
"mediaControls": {
|
||||
"message": "Medien Kontrolle"
|
||||
},
|
||||
"checkForUpdates": {
|
||||
"message": "Nach Updates suchen"
|
||||
},
|
||||
"systemStartup": {
|
||||
"message": "System start"
|
||||
},
|
||||
"presences": {
|
||||
"message": "Presencen"
|
||||
}
|
||||
}
|
||||
104
Extension/_locales/en/messages.json
Normal file
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"appDesc": {
|
||||
"message": "PreMiD adds Discord Rich Presence integration, Media controls and much more to YouTube/YouTube Music, Twitch etc..."
|
||||
},
|
||||
"connected": {
|
||||
"message": "Connected"
|
||||
},
|
||||
"disconnected": {
|
||||
"message": "Disconnected"
|
||||
},
|
||||
"installedThanks": {
|
||||
"message": "Thank you for installing PreMiD"
|
||||
},
|
||||
"installedApp": {
|
||||
"message": "Did you install the application yet?"
|
||||
},
|
||||
"installedNo": {
|
||||
"message": "No? Follow these steps:"
|
||||
},
|
||||
"installedStepApp": {
|
||||
"message": "Download the latest version from $1"
|
||||
},
|
||||
"installedStepAppMyRepository": {
|
||||
"message": "my repository"
|
||||
},
|
||||
"installedWaitInstalled": {
|
||||
"message": "Open the installer and wait until it installed"
|
||||
},
|
||||
"installedMayWarning": {
|
||||
"message": "You may receive a warning about FireWall and SmartScreen (Its not a virus i promise)"
|
||||
},
|
||||
"installedAppAutostart": {
|
||||
"message": "The application should start automatically, you can check this by looking at your taskbar (Windows) or your menubar (MacOS)"
|
||||
},
|
||||
"installedYes": {
|
||||
"message": "Yes? You are ready to go!"
|
||||
},
|
||||
"installedStart": {
|
||||
"message": "Start by watching a video on YouTube, watching your loved streamers on Twitch, Watch your favourite animes on KissAnime or JKAnime, maybe even Netflix... Who knows?<br>Or you just listen to your favourite songs on SoundCloud and YouTube Music. Settings can be found by clicking the PreMiD icon in your browser."
|
||||
},
|
||||
"installedSupportMe": {
|
||||
"message": "Support me!"
|
||||
},
|
||||
"updatedYTPUpdated": {
|
||||
"message": "PreMiD has been updated!"
|
||||
},
|
||||
"updatedWhatsNew": {
|
||||
"message": "Whats new?"
|
||||
},
|
||||
"updatedWhatChanged": {
|
||||
"message": "What changed?"
|
||||
},
|
||||
"playbackPlaying": {
|
||||
"message": "Playing back"
|
||||
},
|
||||
"playbackPaused": {
|
||||
"message": "Playback paused"
|
||||
},
|
||||
"about": {
|
||||
"message": "About"
|
||||
},
|
||||
"feedback": {
|
||||
"message": "Feedback"
|
||||
},
|
||||
"options": {
|
||||
"message": "Options"
|
||||
},
|
||||
"general": {
|
||||
"message": "General"
|
||||
},
|
||||
"enabled": {
|
||||
"message": "Enabled"
|
||||
},
|
||||
"titleMenubar": {
|
||||
"message": "Title Menubar"
|
||||
},
|
||||
"mediaControls": {
|
||||
"message": "Media Controls"
|
||||
},
|
||||
"checkForUpdates": {
|
||||
"message": "Check for updates"
|
||||
},
|
||||
"systemStartup": {
|
||||
"message": "System startup"
|
||||
},
|
||||
"presences": {
|
||||
"message": "Presences"
|
||||
},
|
||||
"updatedAdded0": {
|
||||
"message": "Support for JKAnime & KissAnime"
|
||||
},
|
||||
"updatedAdded1": {
|
||||
"message": "Extension popup"
|
||||
},
|
||||
"updatedAdded2": {
|
||||
"message": "Settings Sync (Google Account)"
|
||||
},
|
||||
"updatedChanged0": {
|
||||
"message": "A lot and I mean a lot of rewrites!"
|
||||
},
|
||||
"updatedChanged1": {
|
||||
"message": "Huge speed improvements to App"
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
//* Used to send response to app
|
||||
function sendAlive() {
|
||||
$.ajax({
|
||||
async: true,
|
||||
crossDomain: true,
|
||||
url: "http://localhost:3000/",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
processData: false,
|
||||
data: JSON.stringify({
|
||||
connected: true,
|
||||
service: "keepAlive"
|
||||
}),
|
||||
error: function(jqXHR, textStatus, errorThrown) {}
|
||||
})
|
||||
}
|
||||
|
||||
setInterval(sendAlive, 1*5000)
|
||||
54
Extension/css/connect.css
Normal file
@@ -0,0 +1,54 @@
|
||||
#ytp-connectinfo {
|
||||
position: fixed;
|
||||
top: -50px;
|
||||
right: 0;
|
||||
z-index: 10000;
|
||||
min-width: 175px;
|
||||
border-bottom-left-radius: 5px;
|
||||
height: 50px;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
user-select: none;
|
||||
animation-name: slideIn;
|
||||
animation-duration: 5s;
|
||||
animation-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
|
||||
color: black;
|
||||
}
|
||||
|
||||
#ytp-connectinfo * {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#ytp-connectinfo img {
|
||||
float: left;
|
||||
margin: 5px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#ytp-connectinfo h1 {
|
||||
font-size: 20px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
#ytp-connectinfo h2 {
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
0% {
|
||||
top: -50px;
|
||||
}
|
||||
|
||||
10% {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
90% {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: -50px;
|
||||
}
|
||||
}
|
||||
78
Extension/css/inputs.css
Normal file
@@ -0,0 +1,78 @@
|
||||
/* The switch - the box around the slider */
|
||||
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 35px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
/* Hide default HTML checkbox */
|
||||
|
||||
.switch input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* The slider */
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgb(255, 75, 75);
|
||||
-webkit-transition: 0.25s;
|
||||
transition: 0.25s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 17px;
|
||||
width: 17px;
|
||||
left: -2.5px;
|
||||
top: -2.5px;
|
||||
background-color: white;
|
||||
-webkit-transition: 0.25s;
|
||||
transition: 0.25s cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
border: 1px solid lightgray;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: rgb(75, 255, 75);
|
||||
}
|
||||
|
||||
input:disabled + .slider {
|
||||
background-color: rgb(255, 75, 75);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
input:disabled + .slider:before {
|
||||
background-color: rgb(255, 75, 75);
|
||||
border: 1px solid rgb(255, 75, 75);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
input:focus + .slider {
|
||||
box-shadow: 0 0 1px rgb(75, 255, 75);
|
||||
}
|
||||
|
||||
input:hover + .slider {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
/* Rounded sliders */
|
||||
|
||||
.slider.round {
|
||||
border-radius: 34px;
|
||||
}
|
||||
|
||||
.slider.round:before {
|
||||
border-radius: 50%;
|
||||
}
|
||||
15
Extension/css/options.css
Normal file
@@ -0,0 +1,15 @@
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#content h1 {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
tr td:first-child {
|
||||
width: 90%;
|
||||
}
|
||||
98
Extension/css/popup.css
Normal file
@@ -0,0 +1,98 @@
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 0;
|
||||
width: 325px;
|
||||
background-color: #282828;
|
||||
}
|
||||
|
||||
#header {
|
||||
height: 50px;
|
||||
background-color: #596cae;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
margin: 0;
|
||||
font-weight: 900;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#header h1:last-child {
|
||||
position: absolute;
|
||||
font-weight: 700;
|
||||
float: right;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#panel {
|
||||
transition: 0.5s all cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
display: inline-block;
|
||||
margin: 5px;
|
||||
width: 150px;
|
||||
height: 125px;
|
||||
background-color: #596cae;
|
||||
border-radius: 5px;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#panel:not(.open) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#panel:not(.open):hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
#panel #icon {
|
||||
margin-top: 25px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
.about {
|
||||
background-color: #ff9d09 !important;
|
||||
}
|
||||
|
||||
.options {
|
||||
background-color: #7a7a7a !important;
|
||||
}
|
||||
|
||||
.github {
|
||||
background-color: #fa503c !important;
|
||||
}
|
||||
|
||||
.open {
|
||||
position: fixed;
|
||||
transition: 0.5s all ease-out;
|
||||
transform: scale(5);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.open * {
|
||||
transition: 0.15s all ease-out;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.panelContent {
|
||||
position: relative;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.panelContent:not(.open) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panelContent.open {
|
||||
display: block;
|
||||
}
|
||||
20
Extension/css/reset.css
Normal file
@@ -0,0 +1,20 @@
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 0;
|
||||
width: 325px;
|
||||
background-color: #282828;
|
||||
}
|
||||
|
||||
* {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#header {
|
||||
height: 50px;
|
||||
background-color: #7289da;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
}
|
||||
106
Extension/css/tab.css
Normal file
@@ -0,0 +1,106 @@
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: 282828;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#header,
|
||||
#footer {
|
||||
background-color: #7289da;
|
||||
color: white;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
#icon {
|
||||
margin: 5px;
|
||||
width: 50px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#title {
|
||||
float: left;
|
||||
font-size: 25px;
|
||||
font-weight: 900;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#version {
|
||||
margin-right: 15px;
|
||||
font-size: 25px;
|
||||
font-weight: 700;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
h1:not(#title):not(#version),
|
||||
h2,
|
||||
h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
position: relative;
|
||||
font-size: 25px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 5px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h2:last-of-type {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 5px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
p,
|
||||
li {
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
a {
|
||||
transition: all 0.25s cubic-bezier(0.6, 0.29, 0.35, 0.85);
|
||||
position: relative;
|
||||
color: rgb(0, 125, 255);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.hu:after {
|
||||
transition: width 0.25s cubic-bezier(0.6, 0.29, 0.35, 0.85);
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -1px;
|
||||
height: 2px;
|
||||
width: 0;
|
||||
background-color: rgb(0, 125, 255);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: rgb(0, 150, 255);
|
||||
}
|
||||
|
||||
a.hu:hover:after {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
//* Start interval
|
||||
window.onload = function() {
|
||||
setInterval(updateData, 1000)
|
||||
}
|
||||
|
||||
//* Create needed variables
|
||||
let urlForVideo,
|
||||
songTime,
|
||||
calcDifference = []
|
||||
|
||||
function updateData() {
|
||||
if (document.location.href.includes("youtube"))
|
||||
urlForVideo = document.location.href
|
||||
if ($(".ytp-time-current").html() != " ") {
|
||||
const data = {
|
||||
connected: true,
|
||||
service: "yt",
|
||||
url: urlForVideo,
|
||||
currentSongTitle: $(".style-scope.ytd-video-primary-info-renderer")
|
||||
.children()
|
||||
.eq(2)
|
||||
.contents()
|
||||
.first()
|
||||
.html(),
|
||||
currentSongAuthor: $(
|
||||
"#upload-info .style-scope .ytd-video-owner-renderer"
|
||||
)
|
||||
.contents()
|
||||
.first()
|
||||
.html(),
|
||||
currentSongStartTime: getSeconds($(".ytp-time-current").html()),
|
||||
currentSongEndTime: getSeconds($(".ytp-time-duration").html()),
|
||||
currentSongCover: "NAN"
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
async: true,
|
||||
crossDomain: true,
|
||||
url: "http://localhost:3000/",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
processData: false,
|
||||
data: JSON.stringify(data),
|
||||
error: function(jqXHR, textStatus, errorThrown) {}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getSeconds(string) {
|
||||
const a = string.split(":")
|
||||
|
||||
const seconds = +a[0] * 60 + +a[1]
|
||||
return seconds
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
//* Start interval
|
||||
$(document).ready(() => {
|
||||
setInterval(updateData, 1000)
|
||||
})
|
||||
|
||||
//* Create needed variables
|
||||
let songTime,
|
||||
splitTime,
|
||||
songStartTime,
|
||||
songEndTime,
|
||||
songTitle,
|
||||
songCover,
|
||||
songAuthors = []
|
||||
|
||||
function updateData() {
|
||||
//* Clear old authors
|
||||
songAuthors = []
|
||||
|
||||
if($(".time-info.style-scope.ytmusic-player-bar").html() != "" &&
|
||||
$(".time-info.style-scope.ytmusic-player-bar").html() != " ") {
|
||||
//* Get song Time String (2:10 / 3:21)
|
||||
songTime = $(".time-info.style-scope.ytmusic-player-bar").html()
|
||||
//* Split to array ["2:10", "3:21"]
|
||||
splitTime = songTime.split(" / ", 2)
|
||||
//* Convert to seconds
|
||||
songStartTime = getSeconds(splitTime[0])
|
||||
songEndTime = getSeconds(splitTime[1])
|
||||
//* Get Song title
|
||||
songTitle = $(".title.style-scope.ytmusic-player-bar").html()
|
||||
//* Get Song cover/thumbnail
|
||||
songCover = $(".image.style-scope.ytmusic-player-bar").attr("src")
|
||||
|
||||
//* Get all authors
|
||||
$(".byline.ytmusic-player-bar").contents().each(function(index, item) {
|
||||
if(item.classList != undefined) {
|
||||
if(item.classList.contains("yt-simple-endpoint") == true) {
|
||||
songAuthors.push(item.innerHTML)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//* If no authors found in previous method use this
|
||||
if(songAuthors.length == 0 || songAuthors.length == 1) {
|
||||
//* Clear old list
|
||||
songAuthors = []
|
||||
songAuthors.push($(".byline.ytmusic-player-bar").contents().first().text())
|
||||
}
|
||||
|
||||
var startTime = Date.now();
|
||||
var endTime =
|
||||
Math.floor(startTime / 1000) -
|
||||
songStartTime +
|
||||
songEndTime;
|
||||
|
||||
const data = {
|
||||
connected: true,
|
||||
service: "ytm",
|
||||
currentSongTitle: songTitle,
|
||||
currentSongAuthors: songAuthors,
|
||||
currentSongStartTimeSeconds: songStartTime,
|
||||
currentSongStartTime: startTime,
|
||||
currentSongEndTime: endTime,
|
||||
currentSongCover: songCover
|
||||
}
|
||||
|
||||
//* Send data to app/server
|
||||
$.ajax({
|
||||
async: true,
|
||||
crossDomain: true,
|
||||
url: "http://localhost:3000/",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
processData: false,
|
||||
data: JSON.stringify(data)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//* Used to extract seconds from Syntax
|
||||
//* 1:39 => 99
|
||||
function getSeconds(string) {
|
||||
const s = string.split(":")
|
||||
|
||||
const seconds = +s[0] * 60 + +s[1]
|
||||
return seconds
|
||||
}
|
||||
137
Extension/html/popup/options.html
Normal file
@@ -0,0 +1,137 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="../../css/reset.css">
|
||||
<link rel="stylesheet" href="../../css/inputs.css">
|
||||
<link rel="stylesheet" href="../../css/options.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="header">
|
||||
<h1 class="Ppreferences"></h1>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1 class="Pgeneral"></h1>
|
||||
<table>
|
||||
<thead>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr id="tPresence">
|
||||
<td class="Penabled"></td>
|
||||
<td class="right">
|
||||
<label class="switch">
|
||||
<input class="togglePresence" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="PmediaControls"></td>
|
||||
<td class="right">
|
||||
<label class="switch">
|
||||
<input class="toggleMediaControls" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="PcheckForUpdates"></td>
|
||||
<td class="right">
|
||||
<label class="switch">
|
||||
<input class="toggleCheckUpdates" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="PsystemStartup"></td>
|
||||
<td class="right">
|
||||
<label class="switch">
|
||||
<input class="toggleSystemStartup" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h1 class="Ppresences"></h1>
|
||||
<table>
|
||||
<thead>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>YouTube</td>
|
||||
<td class="right">
|
||||
<label class="switch">
|
||||
<input class="toggleYouTube" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>YouTube Music</td>
|
||||
<td class="right">
|
||||
<label class="switch">
|
||||
<input class="toggleYouTubeMusic" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Twitch</td>
|
||||
<td class="right">
|
||||
<label class="switch">
|
||||
<input class="toggleTwitch" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SoundCloud</td>
|
||||
<td class="right">
|
||||
<label class="switch">
|
||||
<input class="toggleSoundCloud" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Netflix</td>
|
||||
<td class="right">
|
||||
<label class="switch">
|
||||
<input class="toggleNetflix" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>KissAnime</td>
|
||||
<td class="right">
|
||||
<label class="switch">
|
||||
<input class="toggleKissAnime" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JKAnime</td>
|
||||
<td class="right">
|
||||
<label class="switch">
|
||||
<input class="toggleJKAnime" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script src="../../js/util/jquery-3.3.1.min.js"></script>
|
||||
<script src="../../js/util/socket.io-2.1.1.min.js"></script>
|
||||
<script src="../../js/options.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
28
Extension/html/popup/popup.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz"
|
||||
crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../../css/popup.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="header">
|
||||
<h1 class="Pname"></h1>
|
||||
<h1 class="Pversion"></h1>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div id="panel" class="github">
|
||||
<i id="icon" class="fab fa-github"></i>
|
||||
<h1 id="name">GitHub</h1>
|
||||
</div>
|
||||
<div id="panel" class="options">
|
||||
<i id="icon" class="fas fa-cog"></i>
|
||||
<h1 id="name" class="Poptions"></h1>
|
||||
</div>
|
||||
</div>
|
||||
<script src="../../js/util/jquery-3.3.1.min.js"></script>
|
||||
<script src="../../js/popup.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
36
Extension/html/tabs/installed.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>PreMiD</title>
|
||||
<link rel="stylesheet" href="../../css/tab.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="header">
|
||||
<img id="icon" src="../../icon.png" draggable="false">
|
||||
<h1 id="title">PreMiD</h1>
|
||||
<h1 id="version"></h1>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1 id="installedThanks"></h1>
|
||||
<h2 id="installedApp"></h2>
|
||||
<h3 id="installedNo"></h3>
|
||||
<ul>
|
||||
<li id="installedStepApp"></li>
|
||||
<li id="installedWaitInstalled"></li>
|
||||
<li id="installedMayWarning"></li>
|
||||
<li id="installedAppAutostart"></li>
|
||||
</ul>
|
||||
<h3 id="installedYes"></h3>
|
||||
<p id="installedStart"></p>
|
||||
<h2 id="installedSupportMe"></h2>
|
||||
<a href="https://www.patreon.com/bePatron?u=4610890" target="_blank" data-patreon-widget-type="become-patron-button"><img
|
||||
src="../../images/patreonBTN.png" draggable="false" height="50px" alt="Support me on Patreon!"></a>
|
||||
<a href="https://discord.gg/Kw7WaYn" target="_blank" title="Join our Discord!">
|
||||
<img src="../../images/discord-logo.svg" height="50px" draggable="false" alt="Join my Discord!">
|
||||
</a>
|
||||
</div>
|
||||
<script src="../../js/installed.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
32
Extension/html/tabs/updated.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>PreMiD</title>
|
||||
<link rel="stylesheet" href="../../css/tab.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="header">
|
||||
<img id="icon" src="../../icon.png" draggable="false">
|
||||
<h1 id="title">PreMiD</h1>
|
||||
<h1 id="version"></h1>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1 id="updatedYTPUpdated"></h1>
|
||||
<h2 id="updatedWhatsNew"></h2>
|
||||
<ul id="updatedWhatsNewList">
|
||||
</ul>
|
||||
<h2 id="updatedWhatChanged"></h2>
|
||||
<ul id="updatedWhatChangedList">
|
||||
</ul>
|
||||
<h2 id="installedSupportMe"></h2>
|
||||
<a href="https://www.patreon.com/bePatron?u=4610890" target="_blank" data-patreon-widget-type="become-patron-button"><img
|
||||
src="../../images/patreonBTN.png" draggable="false" height="50px" alt="Support me on Patreon!"></a>
|
||||
<a href="https://discord.gg/Kw7WaYn" target="_blank" title="Join our Discord!">
|
||||
<img src="../../images/discord-logo.svg" height="50px" draggable="false" alt="Join my Discord!">
|
||||
</a>
|
||||
</div>
|
||||
<script src="../../js/updated.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
BIN
Extension/icon.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
1
Extension/images/discord-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 272.1"><style>.st0{fill:#7289DA;}</style><path class="st0" d="M142.8 120.1c-5.7 0-10.2 4.9-10.2 11s4.6 11 10.2 11c5.7 0 10.2-4.9 10.2-11s-4.6-11-10.2-11zM106.3 120.1c-5.7 0-10.2 4.9-10.2 11s4.6 11 10.2 11c5.7 0 10.2-4.9 10.2-11 .1-6.1-4.5-11-10.2-11z"/><path class="st0" d="M191.4 36.9h-134c-11.3 0-20.5 9.2-20.5 20.5v134c0 11.3 9.2 20.5 20.5 20.5h113.4l-5.3-18.3 12.8 11.8 12.1 11.1 21.6 18.7V57.4c-.1-11.3-9.3-20.5-20.6-20.5zm-38.6 129.5s-3.6-4.3-6.6-8c13.1-3.7 18.1-11.8 18.1-11.8-4.1 2.7-8 4.6-11.5 5.9-5 2.1-9.8 3.4-14.5 4.3-9.6 1.8-18.4 1.3-25.9-.1-5.7-1.1-10.6-2.6-14.7-4.3-2.3-.9-4.8-2-7.3-3.4-.3-.2-.6-.3-.9-.5-.2-.1-.3-.2-.4-.2-1.8-1-2.8-1.7-2.8-1.7s4.8 7.9 17.5 11.7c-3 3.8-6.7 8.2-6.7 8.2-22.1-.7-30.5-15.1-30.5-15.1 0-31.9 14.4-57.8 14.4-57.8 14.4-10.7 28-10.4 28-10.4l1 1.2c-18 5.1-26.2 13-26.2 13s2.2-1.2 5.9-2.8c10.7-4.7 19.2-5.9 22.7-6.3.6-.1 1.1-.2 1.7-.2 6.1-.8 13-1 20.2-.2 9.5 1.1 19.7 3.9 30.1 9.5 0 0-7.9-7.5-24.9-12.6l1.4-1.6s13.7-.3 28 10.4c0 0 14.4 25.9 14.4 57.8 0-.1-8.4 14.3-30.5 15zM303.8 79.7h-33.2V117l22.1 19.9v-36.2h11.8c7.5 0 11.2 3.6 11.2 9.4v27.7c0 5.8-3.5 9.7-11.2 9.7h-34v21.1h33.2c17.8.1 34.5-8.8 34.5-29.2v-29.8c.1-20.8-16.6-29.9-34.4-29.9zm174 59.7v-30.6c0-11 19.8-13.5 25.8-2.5l18.3-7.4c-7.2-15.8-20.3-20.4-31.2-20.4-17.8 0-35.4 10.3-35.4 30.3v30.6c0 20.2 17.6 30.3 35 30.3 11.2 0 24.6-5.5 32-19.9l-19.6-9c-4.8 12.3-24.9 9.3-24.9-1.4zM417.3 113c-6.9-1.5-11.5-4-11.8-8.3.4-10.3 16.3-10.7 25.6-.8l14.7-11.3c-9.2-11.2-19.6-14.2-30.3-14.2-16.3 0-32.1 9.2-32.1 26.6 0 16.9 13 26 27.3 28.2 7.3 1 15.4 3.9 15.2 8.9-.6 9.5-20.2 9-29.1-1.8l-14.2 13.3c8.3 10.7 19.6 16.1 30.2 16.1 16.3 0 34.4-9.4 35.1-26.6 1-21.7-14.8-27.2-30.6-30.1zm-67 55.5h22.4V79.7h-22.4v88.8zM728 79.7h-33.2V117l22.1 19.9v-36.2h11.8c7.5 0 11.2 3.6 11.2 9.4v27.7c0 5.8-3.5 9.7-11.2 9.7h-34v21.1H728c17.8.1 34.5-8.8 34.5-29.2v-29.8c0-20.8-16.7-29.9-34.5-29.9zm-162.9-1.2c-18.4 0-36.7 10-36.7 30.5v30.3c0 20.3 18.4 30.5 36.9 30.5 18.4 0 36.7-10.2 36.7-30.5V109c0-20.4-18.5-30.5-36.9-30.5zm14.4 60.8c0 6.4-7.2 9.7-14.3 9.7-7.2 0-14.4-3.1-14.4-9.7V109c0-6.5 7-10 14-10 7.3 0 14.7 3.1 14.7 10v30.3zM682.4 109c-.5-20.8-14.7-29.2-33-29.2h-35.5v88.8h22.7v-28.2h4l20.6 28.2h28L665 138.1c10.7-3.4 17.4-12.7 17.4-29.1zm-32.6 12h-13.2v-20.3h13.2c14.1 0 14.1 20.3 0 20.3z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 120 KiB |
BIN
Extension/images/patreonBTN.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
62
Extension/js/background.js
Normal file
@@ -0,0 +1,62 @@
|
||||
chrome.runtime.onInstalled.addListener(function(details) {
|
||||
switch(details.reason) {
|
||||
case "install": {
|
||||
chrome.tabs.create({url: "html/tabs/installed.html"})
|
||||
break;
|
||||
}
|
||||
case "update": {
|
||||
chrome.tabs.create({url: "html/tabs/updated.html"})
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//* Tab Priority
|
||||
var lastAllowedTab = null,
|
||||
allowedURL = []
|
||||
setInterval(() => {
|
||||
chrome.storage.sync.get(['options'], function(result) {
|
||||
allowedURL = ["www.youtube.com", "music.youtube.com", "twitch.tv", "soundcloud.com", "netflix.com", "kissanime.ac", "kissanime.ru", "jkanime.net"]
|
||||
var options = result.options
|
||||
if(!options.enabled) allowedURL = []
|
||||
if(!options.youtube) allowedURL.remove("www.youtube.com")
|
||||
if(!options.youtubeMusic) allowedURL.remove("music.youtube.com")
|
||||
if(!options.twitch) allowedURL.remove("twitch.tv")
|
||||
if(!options.soundcloud) allowedURL.remove("soundcloud.com")
|
||||
if(!options.netflix) allowedURL.remove("netflix.com")
|
||||
if(!options.kissanime) allowedURL.remove("kissanime.ac") && allowedURL.remove('kissanime.ru')
|
||||
if(!options.jkanime) allowedURL.remove("jkanime.net")
|
||||
})
|
||||
chrome.tabs.getAllInWindow(null, (tabs) => {
|
||||
|
||||
for (var i = 0; i < allowedURL.length; i++) {
|
||||
var currentTab = tabs.find(tab => tab.highlighted)
|
||||
if(currentTab.url.indexOf(allowedURL[i]) > -1) {
|
||||
lastAllowedTab = currentTab.id
|
||||
}
|
||||
}
|
||||
if(lastAllowedTab != null) {
|
||||
chrome.tabs.sendMessage(lastAllowedTab, {"high": true})
|
||||
}
|
||||
})
|
||||
}, 500)
|
||||
|
||||
Array.prototype.remove = function() {
|
||||
var what, a = arguments, L = a.length, ax;
|
||||
while (L && this.length) {
|
||||
what = a[--L];
|
||||
while ((ax = this.indexOf(what)) !== -1) {
|
||||
this.splice(ax, 1);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
//* Create socket connection to application
|
||||
var socket = io.connect('http://localhost:3020/');
|
||||
|
||||
setInterval(() => {
|
||||
chrome.storage.sync.get(['options'], function(result) {
|
||||
socket.emit('settingsChange', result)
|
||||
})
|
||||
}, 1000)
|
||||
11
Extension/js/installed.js
Normal file
@@ -0,0 +1,11 @@
|
||||
document.getElementById('version').innerHTML = 'V' + chrome.runtime.getManifest().version
|
||||
document.getElementById('installedThanks').innerHTML = chrome.i18n.getMessage("installedThanks")
|
||||
document.getElementById('installedApp').innerHTML = chrome.i18n.getMessage("installedApp")
|
||||
document.getElementById('installedNo').innerHTML = chrome.i18n.getMessage("installedNo")
|
||||
document.getElementById('installedStepApp').innerHTML = chrome.i18n.getMessage("installedStepApp", "<a class='hu' target='_blank' href='https://github.com/Timeraa/PreMiD/releases/latest'>" + chrome.i18n.getMessage("installedStepAppMyRepository") + "</a>")
|
||||
document.getElementById('installedWaitInstalled').innerHTML = chrome.i18n.getMessage("installedWaitInstalled")
|
||||
document.getElementById('installedMayWarning').innerHTML = chrome.i18n.getMessage("installedMayWarning")
|
||||
document.getElementById('installedAppAutostart').innerHTML = chrome.i18n.getMessage("installedAppAutostart")
|
||||
document.getElementById('installedYes').innerHTML = chrome.i18n.getMessage("installedYes")
|
||||
document.getElementById('installedStart').innerHTML = chrome.i18n.getMessage("installedStart")
|
||||
document.getElementById('installedSupportMe').innerHTML = chrome.i18n.getMessage("installedSupportMe")
|
||||
140
Extension/js/options.js
Normal file
@@ -0,0 +1,140 @@
|
||||
let options = undefined
|
||||
|
||||
$('.Ppreferences').html(chrome.i18n.getMessage('options'))
|
||||
$('.Pgeneral').html(chrome.i18n.getMessage('general'))
|
||||
$('.Penabled').html(chrome.i18n.getMessage('enabled'))
|
||||
$('.PmediaControls').html(chrome.i18n.getMessage('mediaControls'))
|
||||
$('.PcheckForUpdates').html(chrome.i18n.getMessage('checkForUpdates'))
|
||||
$('.PsystemStartup').html(chrome.i18n.getMessage('systemStartup'))
|
||||
$('.Ppresences').html(chrome.i18n.getMessage('presences'))
|
||||
|
||||
chrome.runtime.getPlatformInfo(function(info) {
|
||||
if(info.os == "mac")
|
||||
$('<tr><td>Title Menubar</td><td><label class="switch"><input class="toggleTitleMenubar" type="checkbox"><span class="slider round"></span></label></td></tr>').insertAfter('#tPresence')
|
||||
titleMenubarToggle = $('.toggleTitleMenubar')
|
||||
titleMenubarToggle.change(tMB);
|
||||
})
|
||||
|
||||
$(document).ready(function() {
|
||||
var enabledToggle = $('.togglePresence'),
|
||||
youtubeToggle = $('.toggleYouTube'),
|
||||
youtubeMusicToggle = $('.toggleYouTubeMusic'),
|
||||
twitchToggle = $('.toggleTwitch'),
|
||||
soundcloudToggle = $('.toggleSoundCloud'),
|
||||
netflixToggle = $('.toggleNetflix'),
|
||||
kissanimeToggle = $('.toggleKissAnime'),
|
||||
jkanimeToggle = $('.toggleJKAnime')
|
||||
mediaControlsToggle = $('.toggleMediaControls')
|
||||
checkForUpdatesToggle = $('.toggleCheckUpdates')
|
||||
systemStartupToggle = $('.toggleSystemStartup')
|
||||
|
||||
enabledToggle.change(tEnabled);
|
||||
youtubeToggle.change(tYT);
|
||||
youtubeMusicToggle.change(tYTM);
|
||||
twitchToggle.change(tT);
|
||||
soundcloudToggle.change(tSC);
|
||||
netflixToggle.change(tN);
|
||||
kissanimeToggle.change(tKA);
|
||||
jkanimeToggle.change(tJKA);
|
||||
mediaControlsToggle.change(tMC);
|
||||
checkForUpdatesToggle.change(tCFU);
|
||||
systemStartupToggle.change(tSS);
|
||||
|
||||
chrome.storage.sync.get(['options'], function(result) {
|
||||
options = result.options
|
||||
if(result.options == undefined) {
|
||||
chrome.storage.sync.set({options: {enabled: true, youtube: true, youtubeMusic: true, twitch: true, soundcloud: true, netflix: true, kissanime: true, jkanime: true, titleMenubar: true, mediaControls: true, checkForUpdates: true, systemStartup: true}})
|
||||
enabledToggle.prop('checked', true)
|
||||
youtubeToggle.prop('checked', true)
|
||||
youtubeMusicToggle.prop('checked', true)
|
||||
twitchToggle.prop('checked', true)
|
||||
soundcloudToggle.prop('checked', true)
|
||||
netflixToggle.prop('checked', true)
|
||||
kissanimeToggle.prop('checked', true)
|
||||
jkanimeToggle.prop('checked', true)
|
||||
if(titleMenubarToggle != undefined)
|
||||
titleMenubarToggle.prop('checked', true)
|
||||
mediaControlsToggle.prop('checked', true)
|
||||
checkForUpdatesToggle.prop('checked', true)
|
||||
systemStartupToggle.prop('checked', true)
|
||||
} else {
|
||||
enabledToggle.prop('checked', result.options.enabled)
|
||||
youtubeToggle.prop('checked', result.options.youtube)
|
||||
youtubeMusicToggle.prop('checked', result.options.youtubeMusic)
|
||||
twitchToggle.prop('checked', result.options.twitch)
|
||||
soundcloudToggle.prop('checked', result.options.soundcloud)
|
||||
netflixToggle.prop('checked', result.options.netflix)
|
||||
kissanimeToggle.prop('checked', result.options.kissanime)
|
||||
jkanimeToggle.prop('checked', result.options.jkanime)
|
||||
if(titleMenubarToggle != undefined)
|
||||
titleMenubarToggle.prop('checked', result.options.titleMenubar)
|
||||
mediaControlsToggle.prop('checked', result.options.mediaControls)
|
||||
checkForUpdatesToggle.prop('checked', result.options.checkForUpdates)
|
||||
systemStartupToggle.prop('checked', result.options.systemStartup)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
function tEnabled() {
|
||||
options.enabled = !options.enabled
|
||||
sync()
|
||||
}
|
||||
|
||||
function tYT() {
|
||||
options.youtube = !options.youtube
|
||||
sync()
|
||||
}
|
||||
|
||||
function tYTM() {
|
||||
options.youtubeMusic = !options.youtubeMusic
|
||||
sync()
|
||||
}
|
||||
|
||||
function tT() {
|
||||
options.twitch = !options.twitch
|
||||
sync()
|
||||
}
|
||||
|
||||
function tSC() {
|
||||
options.soundcloud = !options.soundcloud
|
||||
sync()
|
||||
}
|
||||
|
||||
function tN() {
|
||||
options.netflix = !options.netflix
|
||||
sync()
|
||||
}
|
||||
|
||||
function tKA() {
|
||||
options.kissanime = !options.kissanime
|
||||
sync()
|
||||
}
|
||||
|
||||
function tJKA() {
|
||||
options.jkanime = !options.jkanime
|
||||
sync()
|
||||
}
|
||||
|
||||
function tMB() {
|
||||
options.titleMenubar = !options.titleMenubar
|
||||
sync()
|
||||
}
|
||||
|
||||
function tMC() {
|
||||
options.mediaControls = !options.mediaControls
|
||||
sync()
|
||||
}
|
||||
|
||||
function tCFU() {
|
||||
options.checkForUpdates = !options.checkForUpdates
|
||||
sync()
|
||||
}
|
||||
|
||||
function tSS() {
|
||||
options.systemStartup = !options.systemStartup
|
||||
sync()
|
||||
}
|
||||
|
||||
function sync() {
|
||||
chrome.storage.sync.set({options: options})
|
||||
}
|
||||
20
Extension/js/popup.js
Normal file
@@ -0,0 +1,20 @@
|
||||
$(document).ready(function() {
|
||||
$('.Pname').html(chrome.runtime.getManifest().name)
|
||||
$('.Pversion').html('V' + chrome.runtime.getManifest().version)
|
||||
$('.Pabout').html(chrome.i18n.getMessage('about'))
|
||||
$('.Pfeedback').html(chrome.i18n.getMessage('feedback'))
|
||||
$('.Poptions').html(chrome.i18n.getMessage('options'))
|
||||
|
||||
$('#content #panel').each(function() {
|
||||
this.addEventListener('click', updateItem)
|
||||
})
|
||||
})
|
||||
|
||||
function updateItem() {
|
||||
$(this).addClass('open')
|
||||
setTimeout(() => {
|
||||
if($(this).attr("class").split(' ')[0] == "github") {
|
||||
chrome.tabs.create({url: 'https://github.com/Timeraa/PreMiD'})
|
||||
} else window.location.href= $(this).attr("class").split(' ')[0] + ".html";
|
||||
}, 350)
|
||||
}
|
||||
146
Extension/js/presences/JKAnime.js
Normal file
@@ -0,0 +1,146 @@
|
||||
let videoRunning = false,
|
||||
tabActive = 0,
|
||||
dataUpdaterRunning = false,
|
||||
dataUpdater
|
||||
|
||||
//* Update data and send to application
|
||||
$(document).ready(() => {
|
||||
setInterval(playbackChange, 250)
|
||||
//* Tab Priority
|
||||
setInterval(() => {
|
||||
if(tabActive == 5) {
|
||||
dataUpdaterRunning = false
|
||||
videoRunning = false
|
||||
clearInterval(dataUpdater)
|
||||
}
|
||||
if(tabActive >= 9 && dataUpdaterRunning == false) {
|
||||
dataUpdaterRunning = true
|
||||
dataUpdater = setInterval(updateData, 1000)
|
||||
}
|
||||
if(tabActive > 0) tabActive--
|
||||
}, 500)
|
||||
})
|
||||
|
||||
chrome.runtime.onMessage.addListener(((message, sender) => {
|
||||
if(tabActive <= 9) tabActive += 2
|
||||
if(tabActive == 0) tabActive = 5
|
||||
}))
|
||||
|
||||
//* Handle Media Keys from sent by application
|
||||
socket.on('mediaKeyHandler', handleMediaKeys)
|
||||
|
||||
/**
|
||||
* Handles Media Keys for easy media control
|
||||
* @param {Object} data Data received from socket
|
||||
*/
|
||||
function handleMediaKeys(data) {
|
||||
//* Check if the data is for YTM & if music is running
|
||||
//* Media control buttons
|
||||
if (videoRunning) {
|
||||
//* Switch cases for playback / Clicks corresponding buttons
|
||||
switch (data.playback) {
|
||||
case "pause":
|
||||
$('.server-box iframe:first').contents().find('video:first')[0].paused ? $('.server-box iframe:first').contents().find('video:first')[0].play() : $('.server-box iframe:first').contents().find('video:first')[0].pause()
|
||||
updateData("playPauseTrack")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Data and send it to the App
|
||||
* @param {String} playbackChange Playback if changed
|
||||
*/
|
||||
function updateData(playbackChange = false) {
|
||||
var eventType
|
||||
videoRunning = $('.video-header h1').html() != "" && $('.server-box iframe:first').contents().find('video:first')[0] != undefined && !isNaN($('.server-box iframe:first').contents().find('video:first')[0].duration) ? true : false
|
||||
if(videoRunning) {
|
||||
var videoTitle = $('.video-header h1').html(),
|
||||
videoEpisode = 'Episode ' + $('.video-header h1').html().split(' - ').pop(),
|
||||
videoTimeSeconds = Math.floor($('.server-box iframe:first').contents().find('video:first')[0].currentTime),
|
||||
videoDurationSeconds = Math.floor($('.server-box iframe:first').contents().find('video:first')[0].duration),
|
||||
videoTimestamps = getTimestamps(videoTimeSeconds, videoDurationSeconds)
|
||||
playback = $('.server-box iframe:first').contents().find('video:first')[0].paused ? "paused" : "playing"
|
||||
|
||||
if (playbackChange) eventType = 'playBackChange'; else eventType = 'updateData';
|
||||
|
||||
var playbackBoolean = !$('.server-box iframe:first').contents().find('video:first')[0].paused
|
||||
|
||||
var smallImageKey = playbackBoolean ? 'play' : 'pause',
|
||||
smallImageText = playbackBoolean ? chrome.i18n.getMessage('playbackPlaying') : chrome.i18n.getMessage('playbackPaused')
|
||||
|
||||
if(playbackBoolean) {
|
||||
var data = {
|
||||
clientID: '505709790811389962',
|
||||
presenceData: {
|
||||
details: $('<div/>').html(videoTitle).text(),
|
||||
state: $('<div/>').html(videoEpisode).text(),
|
||||
largeImageKey: 'jka_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText,
|
||||
startTimestamp: videoTimestamps[0],
|
||||
endTimestamp: videoTimestamps[1]
|
||||
},
|
||||
currentSeconds: videoTimeSeconds,
|
||||
durationSeconds: videoDurationSeconds,
|
||||
trayTitle: $('<div/>').html(videoTitle).text(),
|
||||
playback: playbackBoolean,
|
||||
service: 'JKAnime'
|
||||
}
|
||||
} else {
|
||||
var data = {
|
||||
clientID: '505709790811389962',
|
||||
presenceData: {
|
||||
details: $('<div/>').html(videoTitle).text(),
|
||||
state: $('<div/>').html(videoEpisode).text(),
|
||||
largeImageKey: 'jka_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText,
|
||||
},
|
||||
currentSeconds: videoTimeSeconds,
|
||||
durationSeconds: videoDurationSeconds,
|
||||
trayTitle: $('<div/>').html(videoTitle).text(),
|
||||
playback: playbackBoolean,
|
||||
service: 'JKAnime'
|
||||
}
|
||||
}
|
||||
console.log(data)
|
||||
}
|
||||
if(socket.connected) socket.emit(eventType, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Timestamps
|
||||
* @param {Number} videoTime Song Time
|
||||
* @param {Number} videoDuration Song Duration
|
||||
*/
|
||||
function getTimestamps(videoTime, videoDuration) {
|
||||
var startTime = Date.now();
|
||||
var endTime =
|
||||
Math.floor(startTime / 1000) -
|
||||
videoTime +
|
||||
videoDuration;
|
||||
return [Math.floor(startTime/1000), endTime]
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles playback
|
||||
*/
|
||||
function togglePlayback() {
|
||||
//* Toggle playback variable
|
||||
playback = !playback
|
||||
//* Send status to application
|
||||
updateData(playback ? "playing" : "paused")
|
||||
}
|
||||
|
||||
var lastPlayback = false
|
||||
function playbackChange() {
|
||||
if(videoRunning) {
|
||||
if($('.server-box iframe:first').contents().find('video:first')[0].paused != lastPlayback) {
|
||||
togglePlayback()
|
||||
lastPlayback = $('.server-box iframe:first').contents().find('video:first')[0].paused
|
||||
}
|
||||
}
|
||||
}
|
||||
145
Extension/js/presences/KissAnime.js
Normal file
@@ -0,0 +1,145 @@
|
||||
let videoRunning = false,
|
||||
tabActive = 0,
|
||||
dataUpdaterRunning = false,
|
||||
dataUpdater
|
||||
|
||||
//* Update data and send to application
|
||||
$(document).ready(() => {
|
||||
setInterval(playbackChange, 250)
|
||||
//* Tab Priority
|
||||
setInterval(() => {
|
||||
if(tabActive == 5) {
|
||||
dataUpdaterRunning = false
|
||||
videoRunning = false
|
||||
clearInterval(dataUpdater)
|
||||
}
|
||||
if(tabActive >= 9 && dataUpdaterRunning == false) {
|
||||
dataUpdaterRunning = true
|
||||
dataUpdater = setInterval(updateData, 1000)
|
||||
}
|
||||
if(tabActive > 0) tabActive--
|
||||
}, 500)
|
||||
})
|
||||
|
||||
chrome.runtime.onMessage.addListener(((message, sender) => {
|
||||
if(tabActive <= 9) tabActive += 2
|
||||
if(tabActive == 0) tabActive = 5
|
||||
}))
|
||||
|
||||
//* Handle Media Keys from sent by application
|
||||
socket.on('mediaKeyHandler', handleMediaKeys)
|
||||
|
||||
/**
|
||||
* Handles Media Keys for easy media control
|
||||
* @param {Object} data Data received from socket
|
||||
*/
|
||||
function handleMediaKeys(data) {
|
||||
//* Check if the data is for YTM & if music is running
|
||||
//* Media control buttons
|
||||
if (videoRunning) {
|
||||
//* Switch cases for playback / Clicks corresponding buttons
|
||||
switch (data.playback) {
|
||||
case "pause":
|
||||
$('#player_html5_html5_api')[0].paused ? $('#player_html5_html5_api')[0].play() : $('#player_html5_html5_api')[0].pause()
|
||||
updateData("playPauseTrack")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Data and send it to the App
|
||||
* @param {String} playbackChange Playback if changed
|
||||
*/
|
||||
function updateData(playbackChange = false) {
|
||||
var eventType
|
||||
videoRunning = $('.movie_back_link strong').html() != "" && $('#player_html5_html5_api')[0] != undefined && !isNaN($('#player_html5_html5_api')[0].duration) ? true : false
|
||||
if(videoRunning) {
|
||||
var videoTitle = $('.movie_back_link strong').html(),
|
||||
videoEpisode = $('#selectEpisode option:selected').text().trim(),
|
||||
videoTimeSeconds = Math.floor($('#player_html5_html5_api')[0].currentTime),
|
||||
videoDurationSeconds = Math.floor($('#player_html5_html5_api')[0].duration),
|
||||
videoTimestamps = getTimestamps(videoTimeSeconds, videoDurationSeconds)
|
||||
playback = $('#player_html5_html5_api')[0].paused ? "paused" : "playing"
|
||||
|
||||
if (playbackChange) eventType = 'playBackChange'; else eventType = 'updateData';
|
||||
|
||||
var playbackBoolean = !$('#player_html5_html5_api')[0].paused
|
||||
|
||||
var smallImageKey = playbackBoolean ? 'play' : 'pause',
|
||||
smallImageText = playbackBoolean ? chrome.i18n.getMessage('playbackPlaying') : chrome.i18n.getMessage('playbackPaused')
|
||||
|
||||
if(playbackBoolean) {
|
||||
var data = {
|
||||
clientID: '505704053238398986',
|
||||
presenceData: {
|
||||
details: $('<div/>').html(videoTitle).text(),
|
||||
state: $('<div/>').html(videoEpisode).text(),
|
||||
largeImageKey: 'ka_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText,
|
||||
startTimestamp: videoTimestamps[0],
|
||||
endTimestamp: videoTimestamps[1]
|
||||
},
|
||||
currentSeconds: videoTimeSeconds,
|
||||
durationSeconds: videoDurationSeconds,
|
||||
trayTitle: $('<div/>').html(videoTitle).text(),
|
||||
playback: playbackBoolean,
|
||||
service: 'KissAnime'
|
||||
}
|
||||
} else {
|
||||
var data = {
|
||||
clientID: '505704053238398986',
|
||||
presenceData: {
|
||||
details: $('<div/>').html(videoTitle).text(),
|
||||
state: $('<div/>').html(videoEpisode).text(),
|
||||
largeImageKey: 'ka_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText,
|
||||
},
|
||||
currentSeconds: videoTimeSeconds,
|
||||
durationSeconds: videoDurationSeconds,
|
||||
trayTitle: $('<div/>').html(videoTitle).text(),
|
||||
playback: playbackBoolean,
|
||||
service: 'KissAnime'
|
||||
}
|
||||
}
|
||||
}
|
||||
if(socket.connected) socket.emit(eventType, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Timestamps
|
||||
* @param {Number} videoTime Song Time
|
||||
* @param {Number} videoDuration Song Duration
|
||||
*/
|
||||
function getTimestamps(videoTime, videoDuration) {
|
||||
var startTime = Date.now();
|
||||
var endTime =
|
||||
Math.floor(startTime / 1000) -
|
||||
videoTime +
|
||||
videoDuration;
|
||||
return [Math.floor(startTime/1000), endTime]
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles playback
|
||||
*/
|
||||
function togglePlayback() {
|
||||
//* Toggle playback variable
|
||||
playback = !playback
|
||||
//* Send status to application
|
||||
updateData(playback ? "playing" : "paused")
|
||||
}
|
||||
|
||||
var lastPlayback = false
|
||||
function playbackChange() {
|
||||
if(videoRunning) {
|
||||
if($('#player_html5_html5_api')[0].paused != lastPlayback) {
|
||||
togglePlayback()
|
||||
lastPlayback = $('#player_html5_html5_api')[0].paused
|
||||
}
|
||||
}
|
||||
}
|
||||
156
Extension/js/presences/Netflix.js
Normal file
@@ -0,0 +1,156 @@
|
||||
let playback = true,
|
||||
eventType,
|
||||
playbackNew,
|
||||
tabActive = 0,
|
||||
dataUpdaterRunning = false,
|
||||
dataUpdater
|
||||
|
||||
var lastPlaybackState = true
|
||||
setInterval(() => {
|
||||
if($('.VideoContainer div video')[0] != null && $('.VideoContainer div video')[0].paused && lastPlaybackState == true) {
|
||||
handlePlayPause()
|
||||
lastPlaybackState = false;
|
||||
}
|
||||
if($('.VideoContainer div video')[0] != null && !$('.VideoContainer div video')[0].paused && lastPlaybackState == false) {
|
||||
handlePlayPause()
|
||||
lastPlaybackState = true;
|
||||
}
|
||||
}, 500)
|
||||
|
||||
//* When we receive messages from the application
|
||||
socket.on('mediaKeyHandler', function (data) {
|
||||
//* Check if the data is for YTM & if music is running
|
||||
//* Media control buttons
|
||||
if (musicRunning) {
|
||||
//* Switch cases for playback / Clicks corresponding buttons
|
||||
switch (data.playback) {
|
||||
case "pause":
|
||||
$('.VideoContainer div video')[0].paused ? $('.VideoContainer div video')[0].play() : $('.VideoContainer div video')[0].pause()
|
||||
updateData("playPauseVideo")
|
||||
break
|
||||
case "nextTrack":
|
||||
$('.button-nfplayerNextEpisode').click()
|
||||
//* Prevent playback from being paused again
|
||||
playback = true
|
||||
//* Send response back to application
|
||||
updateData("nextVideo")
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
function handlePlayPause() {
|
||||
//* Toggle playback variable
|
||||
if (playback == true) playback = false; else playback = true;
|
||||
//* Send status to application
|
||||
updateData(playback ? "playing" : "paused")
|
||||
}
|
||||
|
||||
function checkPlayChange() {
|
||||
//* Correct playback if out of sync
|
||||
if (playback == false) {
|
||||
//* Check if playbutton on page matches variable
|
||||
if ($('.ytp-play-button svg').prop("outerHTML") == playButton) {
|
||||
//* Update playback variable
|
||||
playback = true
|
||||
//* Pause song
|
||||
$('.ytp-play-button').click()
|
||||
}
|
||||
}
|
||||
|
||||
//* Set musicRunning variable to true if url has /watch or music title not empty
|
||||
if (document.location.pathname.includes("/watch")) musicRunning = true; else musicRunning = false;
|
||||
}
|
||||
|
||||
//* Start interval
|
||||
window.onload = function () {
|
||||
//* Tab Priority
|
||||
setInterval(() => {
|
||||
if(tabActive == 5) {
|
||||
dataUpdaterRunning = false
|
||||
clearInterval(dataUpdater)
|
||||
}
|
||||
if(tabActive >= 9 && dataUpdaterRunning == false) {
|
||||
dataUpdaterRunning = true
|
||||
dataUpdater = setInterval(updateData, 1000)
|
||||
}
|
||||
if(tabActive > 0) tabActive--
|
||||
}, 500)
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener(((message, sender) => {
|
||||
if(tabActive <= 9) tabActive += 2
|
||||
if(tabActive == 0) tabActive = 5
|
||||
}))
|
||||
|
||||
//* Create needed variables
|
||||
let urlForVideo,
|
||||
songTime,
|
||||
calcDifference = []
|
||||
|
||||
function updateData(playbackChange = false) {
|
||||
if (document.location.pathname.includes("/watch")) musicRunning = true; else musicRunning = false;
|
||||
urlForVideo = document.location.href
|
||||
if ($(".time-remaining__time").html() != "") {
|
||||
let data
|
||||
|
||||
if (playbackChange != false) {
|
||||
var eventType = 'playBackChange'
|
||||
} else {
|
||||
var eventType = 'updateData'
|
||||
}
|
||||
|
||||
var endTime
|
||||
if(musicRunning && $('.VideoContainer div video')[0] != undefined) {
|
||||
var startTime = Math.floor(Date.now()/1000);
|
||||
endTime = startTime -
|
||||
Math.floor($('.VideoContainer div video')[0].currentTime) +
|
||||
Math.floor($('.VideoContainer div video')[0].duration);
|
||||
|
||||
var playbackBoolean = !$('.VideoContainer div video')[0].paused
|
||||
|
||||
var smallImageKey = playbackBoolean ? "play" : "pause"
|
||||
smallImageText = playbackBoolean ? chrome.i18n.getMessage('playbackPlaying') : chrome.i18n.getMessage('playbackPaused')
|
||||
|
||||
if(playbackBoolean) {
|
||||
data = {
|
||||
clientID: '499981204045430784',
|
||||
presenceData: {
|
||||
details: $('.ellipsize-text').children().html(),
|
||||
state: $($('.ellipsize-text').children().get(1)).html(),
|
||||
largeImageKey: 'nflix_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText,
|
||||
startTimestamp: startTime,
|
||||
endTimestamp: endTime
|
||||
},
|
||||
currentSeconds: Math.floor($('.VideoContainer div video')[0].currentTime),
|
||||
durationSeconds: Math.floor($('.VideoContainer div video')[0].duration),
|
||||
trayTitle: $('.ellipsize-text').children().html(),
|
||||
playback: playbackBoolean,
|
||||
service: 'Netflix'
|
||||
}
|
||||
} else {
|
||||
data = {
|
||||
clientID: '499981204045430784',
|
||||
presenceData: {
|
||||
details: $('.ellipsize-text').children().html(),
|
||||
state: $($('.ellipsize-text').children().get(1)).html(),
|
||||
largeImageKey: 'nflix_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText
|
||||
},
|
||||
currentSeconds: Math.floor($('.VideoContainer div video')[0].currentTime),
|
||||
durationSeconds: Math.floor($('.VideoContainer div video')[0].duration),
|
||||
trayTitle: $('.ellipsize-text').children().html(),
|
||||
playback: playbackBoolean,
|
||||
service: 'Netflix'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (socket.connected) socket.emit(eventType, data)
|
||||
}
|
||||
}
|
||||
182
Extension/js/presences/SoundCloud.js
Normal file
@@ -0,0 +1,182 @@
|
||||
|
||||
let playback = true,
|
||||
eventType,
|
||||
playbackNew,
|
||||
tabActive = 0,
|
||||
dataUpdaterRunning = false,
|
||||
dataUpdater
|
||||
|
||||
var lastPlaybackState = true
|
||||
setInterval(() => {
|
||||
if($('.playControl').hasClass('playing') && lastPlaybackState == true) {
|
||||
handlePlayPause()
|
||||
lastPlaybackState = false;
|
||||
}
|
||||
if(!$('.playControl').hasClass('playing') && lastPlaybackState == false) {
|
||||
handlePlayPause()
|
||||
lastPlaybackState = true;
|
||||
}
|
||||
}, 500)
|
||||
|
||||
//* When we receive messages from the application
|
||||
socket.on('mediaKeyHandler', function (data) {
|
||||
//* Check if the data is for YTM & if music is running
|
||||
//* Media control buttons
|
||||
if ($('.playControl') != undefined) {
|
||||
//* Switch cases for playback / Clicks corresponding buttons
|
||||
switch (data.playback) {
|
||||
case "pause":
|
||||
$('.playControl').click()
|
||||
updateData("playPauseVideo")
|
||||
break
|
||||
case "nextTrack":
|
||||
$('.skipControl__next').click()
|
||||
//* Prevent playback from being paused again
|
||||
playback = true
|
||||
//* Send response back to application
|
||||
updateData("nextVideo")
|
||||
break
|
||||
case "previousTrack":
|
||||
$('.skipControl__previous').click()
|
||||
//* Prevent playback from being paused again
|
||||
playback = true
|
||||
//* Send response back to application
|
||||
updateData("nextVideo")
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
function handlePlayPause() {
|
||||
//* Toggle playback variable
|
||||
if (playback == true) playback = false; else playback = true;
|
||||
//* Send status to application
|
||||
updateData(playback ? "playing" : "paused")
|
||||
}
|
||||
|
||||
function checkPlayChange() {
|
||||
//* Correct playback if out of sync
|
||||
if (playback == false) {
|
||||
//* Check if playbutton on page matches variable
|
||||
if ($('.ytp-play-button svg').prop("outerHTML") == playButton) {
|
||||
//* Update playback variable
|
||||
playback = true
|
||||
//* Pause song
|
||||
$('.ytp-play-button').click()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//* Start interval
|
||||
window.onload = function () {
|
||||
//* Tab Priority
|
||||
setInterval(() => {
|
||||
if(tabActive == 5) {
|
||||
dataUpdaterRunning = false
|
||||
clearInterval(dataUpdater)
|
||||
}
|
||||
if(tabActive >= 9 && dataUpdaterRunning == false) {
|
||||
dataUpdaterRunning = true
|
||||
dataUpdater = setInterval(updateData, 1000)
|
||||
}
|
||||
if(tabActive > 0) tabActive--
|
||||
}, 500)
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener(((message, sender) => {
|
||||
if(tabActive <= 9) tabActive += 2
|
||||
if(tabActive == 0) tabActive = 5
|
||||
}))
|
||||
|
||||
//* Create needed variables
|
||||
let urlForVideo,
|
||||
songTime,
|
||||
calcDifference = []
|
||||
|
||||
function updateData(playbackChange = false) {
|
||||
urlForVideo = document.location.href
|
||||
if ($(".time-remaining__time").html() != "") {
|
||||
let data
|
||||
|
||||
if (playbackChange != false) {
|
||||
var eventType = 'playBackChange'
|
||||
} else {
|
||||
var eventType = 'updateData'
|
||||
}
|
||||
|
||||
var endTime
|
||||
if($('.playbackSoundBadge__titleContextContainer') != undefined) {
|
||||
var startTime = Math.floor(Date.now()/1000);
|
||||
endTime = startTime -
|
||||
getSeconds($('.playbackTimeline__timePassed').children().get(1).innerHTML) + getSeconds($('.playbackTimeline__duration').children().get(1).innerHTML);
|
||||
|
||||
var playbackBoolean = $('.playControl').hasClass('playing')
|
||||
|
||||
var smallImageKey = playbackBoolean ? 'play' : 'pause',
|
||||
smallImageText = playbackBoolean ? chrome.i18n.getMessage('playbackPlaying') : chrome.i18n.getMessage('playbackPaused')
|
||||
|
||||
|
||||
var songTitle = $('.playbackSoundBadge__titleLink').children().get(1).innerHTML,
|
||||
songAuthorsString = $('.playbackSoundBadge__titleContextContainer').children().get(0).innerHTML;
|
||||
if(playbackBoolean) {
|
||||
data = {
|
||||
clientID: '501021185887436810',
|
||||
presenceData: {
|
||||
details: $('<div/>').html(songTitle).text(),
|
||||
state: $('<div/>').html(songAuthorsString).text(),
|
||||
largeImageKey: 'scloud_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText,
|
||||
startTimestamp: startTime,
|
||||
endTimestamp: endTime
|
||||
},
|
||||
currentSeconds: getSeconds($('.playbackTimeline__timePassed').children().get(1).innerHTML),
|
||||
durationSeconds: getSeconds($('.playbackTimeline__duration').children().get(1).innerHTML),
|
||||
trayTitle: $('<div/>').html(songTitle).text(),
|
||||
playback: playbackBoolean,
|
||||
service: 'SoundCloud'
|
||||
}
|
||||
} else {
|
||||
data = {
|
||||
clientID: '501021185887436810',
|
||||
presenceData: {
|
||||
details: $('<div/>').html(songTitle).text(),
|
||||
state: $('<div/>').html(songAuthorsString).text(),
|
||||
largeImageKey: 'scloud_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText
|
||||
},
|
||||
currentSeconds: getSeconds($('.playbackTimeline__timePassed').children().get(1).innerHTML),
|
||||
durationSeconds: getSeconds($('.playbackTimeline__duration').children().get(1).innerHTML),
|
||||
trayTitle: $('<div/>').html(songTitle).text(),
|
||||
playback: playbackBoolean,
|
||||
service: 'SoundCloud'
|
||||
}
|
||||
}
|
||||
|
||||
/*data = {
|
||||
scloud: {
|
||||
url: urlForVideo,
|
||||
songTitle: $('.playbackSoundBadge__titleLink').children().get(1).innerHTML,
|
||||
songAuthor: $('.playbackSoundBadge__titleContextContainer').children().get(0).innerHTML,
|
||||
songCurrentTimeSeconds: getSeconds($('.playbackTimeline__timePassed').children().get(1).innerHTML),
|
||||
songEndTimeSeconds: getSeconds($('.playbackTimeline__duration').children().get(1).innerHTML),
|
||||
songCurrentTime: startTime,
|
||||
songEndTime: endTime,
|
||||
playback: $('.playControl').hasClass('playing') ? "playing" : "paused"
|
||||
}
|
||||
} */
|
||||
}
|
||||
if (socket.connected) socket.emit(eventType, data)
|
||||
}
|
||||
}
|
||||
|
||||
function getSeconds(string) {
|
||||
const a = string.split(":")
|
||||
|
||||
const seconds = +a[0] * 60 + +a[1]
|
||||
return seconds
|
||||
}
|
||||
175
Extension/js/presences/Twitch.js
Normal file
@@ -0,0 +1,175 @@
|
||||
let playback = true,
|
||||
eventType,
|
||||
playbackNew,
|
||||
lastURL = null,
|
||||
startTimeStamp,
|
||||
tabActive = 0,
|
||||
dataUpdaterRunning = false,
|
||||
dataUpdater;
|
||||
|
||||
var lastPlaybackState = true;
|
||||
setInterval(() => {
|
||||
if (
|
||||
$(".player-video video")[0] != null &&
|
||||
$(".player-video video")[0].paused &&
|
||||
lastPlaybackState == true
|
||||
) {
|
||||
handlePlayPause();
|
||||
lastPlaybackState = false;
|
||||
}
|
||||
if (
|
||||
$(".player-video video")[0] != null &&
|
||||
!$(".player-video video")[0].paused &&
|
||||
lastPlaybackState == false
|
||||
) {
|
||||
handlePlayPause();
|
||||
lastPlaybackState = true;
|
||||
}
|
||||
}, 500);
|
||||
|
||||
//* When we receive messages from the application
|
||||
socket.on("mediaKeyHandler", function(data) {
|
||||
//* Check if the data is for twitch & if music is running
|
||||
//* Media control buttons
|
||||
if ($(".player-video video")[0] != null) {
|
||||
//* Switch cases for playback / Clicks corresponding buttons
|
||||
switch (data.playback) {
|
||||
case "pause":
|
||||
$(".player-video video")[0].paused
|
||||
? $(".qa-pause-play-button").click()
|
||||
: $(".qa-pause-play-button").click();
|
||||
updateData("playPauseVideo");
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function handlePlayPause() {
|
||||
//* Toggle playback variable
|
||||
if (playback == true) playback = false;
|
||||
else playback = true;
|
||||
//* Send status to application
|
||||
updateData(playback ? "playing" : "paused");
|
||||
}
|
||||
|
||||
function checkPlayChange() {
|
||||
//* Correct playback if out of sync
|
||||
if (playback == false) {
|
||||
//* Check if playbutton on page matches variable
|
||||
if ($(".ytp-play-button svg").prop("outerHTML") == playButton) {
|
||||
//* Update playback variable
|
||||
playback = true;
|
||||
//* Pause song
|
||||
$(".ytp-play-button").click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//* Start interval
|
||||
window.onload = function() {
|
||||
//* Tab Priority
|
||||
setInterval(() => {
|
||||
if (tabActive == 5) {
|
||||
dataUpdaterRunning = false;
|
||||
clearInterval(dataUpdater);
|
||||
}
|
||||
if (tabActive >= 9 && dataUpdaterRunning == false) {
|
||||
dataUpdaterRunning = true;
|
||||
dataUpdater = setInterval(updateData, 1000);
|
||||
}
|
||||
if (tabActive > 0) tabActive--;
|
||||
}, 500);
|
||||
};
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender) => {
|
||||
if (tabActive <= 9) tabActive += 2;
|
||||
if (tabActive == 0) tabActive = 5;
|
||||
});
|
||||
|
||||
//* Create needed variables
|
||||
let urlForVideo,
|
||||
songTime,
|
||||
calcDifference = [];
|
||||
|
||||
function updateData(playbackChange = false) {
|
||||
urlForVideo = document.location.href;
|
||||
|
||||
if (playbackChange != false) {
|
||||
var eventType = "playBackChange";
|
||||
} else {
|
||||
var eventType = "updateData";
|
||||
}
|
||||
|
||||
if (
|
||||
$(".player-video video")[0] != undefined &&
|
||||
$(".tw-ellipsis.tw-mg-b-05").children().length > 0
|
||||
) {
|
||||
if (urlForVideo != lastURL) {
|
||||
lastURL = urlForVideo;
|
||||
startTimeStamp = Math.floor(Date.now() / 1000);
|
||||
}
|
||||
|
||||
var playbackBoolean = !$(".player-video video")[0].paused;
|
||||
|
||||
var smallImageKey = playbackBoolean ? "play" : "pause",
|
||||
smallImageText = playbackBoolean
|
||||
? chrome.i18n.getMessage("playbackPlaying")
|
||||
: chrome.i18n.getMessage("playbackPaused");
|
||||
|
||||
var streamTitle = $(".tw-ellipsis.tw-mg-b-05")
|
||||
.children()
|
||||
.get(0).innerHTML,
|
||||
streamHost = $(".channel-header__user h5").html();
|
||||
if (playbackBoolean) {
|
||||
var data = {
|
||||
clientID: "501021996336021504",
|
||||
presenceData: {
|
||||
details: $("<div/>")
|
||||
.html(streamTitle)
|
||||
.text(),
|
||||
state: $("<div/>")
|
||||
.html(streamHost)
|
||||
.text(),
|
||||
largeImageKey: "twitch_lg",
|
||||
largeImageText:
|
||||
chrome.runtime.getManifest().name +
|
||||
" V" +
|
||||
chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText,
|
||||
startTimestamp: startTimeStamp
|
||||
},
|
||||
trayTitle: $("<div/>")
|
||||
.html(streamTitle)
|
||||
.text(),
|
||||
playback: playbackBoolean,
|
||||
service: "Twitch"
|
||||
};
|
||||
} else {
|
||||
var data = {
|
||||
clientID: "501021996336021504",
|
||||
presenceData: {
|
||||
details: $("<div/>")
|
||||
.html(streamTitle)
|
||||
.text(),
|
||||
state: $("<div/>")
|
||||
.html(streamHost)
|
||||
.text(),
|
||||
largeImageKey: "twitch_lg",
|
||||
largeImageText:
|
||||
chrome.runtime.getManifest().name +
|
||||
" V" +
|
||||
chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText
|
||||
},
|
||||
trayTitle: $("<div/>")
|
||||
.html(streamTitle)
|
||||
.text(),
|
||||
playback: playbackBoolean,
|
||||
service: "Twitch"
|
||||
};
|
||||
}
|
||||
}
|
||||
if (socket.connected) socket.emit(eventType, data);
|
||||
}
|
||||
155
Extension/js/presences/YouTube.js
Normal file
@@ -0,0 +1,155 @@
|
||||
let videoRunning = false,
|
||||
tabActive = 0,
|
||||
dataUpdaterRunning = false,
|
||||
dataUpdater
|
||||
|
||||
//* Update data and send to application
|
||||
$(document).ready(() => {
|
||||
setInterval(playbackChange, 250)
|
||||
//* Tab Priority
|
||||
setInterval(() => {
|
||||
if(tabActive == 5) {
|
||||
dataUpdaterRunning = false
|
||||
videoRunning = false
|
||||
clearInterval(dataUpdater)
|
||||
}
|
||||
if(tabActive >= 9 && dataUpdaterRunning == false) {
|
||||
dataUpdaterRunning = true
|
||||
dataUpdater = setInterval(updateData, 1000)
|
||||
}
|
||||
if(tabActive > 0) tabActive--
|
||||
}, 500)
|
||||
})
|
||||
|
||||
chrome.runtime.onMessage.addListener(((message, sender) => {
|
||||
if(tabActive <= 9) tabActive += 2
|
||||
if(tabActive == 0) tabActive = 5
|
||||
}))
|
||||
|
||||
//* Handle Media Keys from sent by application
|
||||
socket.on('mediaKeyHandler', handleMediaKeys)
|
||||
|
||||
/**
|
||||
* Handles Media Keys for easy media control
|
||||
* @param {Object} data Data received from socket
|
||||
*/
|
||||
function handleMediaKeys(data) {
|
||||
//* Check if the data is for YTM & if music is running
|
||||
//* Media control buttons
|
||||
if (videoRunning) {
|
||||
//* Switch cases for playback / Clicks corresponding buttons
|
||||
switch (data.playback) {
|
||||
case "pause":
|
||||
$('.ytp-play-button').click()
|
||||
updateData("playPauseTrack")
|
||||
break
|
||||
case "nextTrack":
|
||||
$('.ytp-next-button')[0].click()
|
||||
//* Send response back to application
|
||||
updateData("nextTrack")
|
||||
break
|
||||
case "previousTrack":
|
||||
$('.ytp-prev-button')[0].click()
|
||||
//* Send response back to application
|
||||
updateData("previousTrack")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Data and send it to the App
|
||||
* @param {String} playbackChange Playback if changed
|
||||
*/
|
||||
function updateData(playbackChange = false) {
|
||||
var eventType
|
||||
videoRunning = $('.ytd-video-primary-info-renderer .title').text() != "" && $('.video-stream')[0] != undefined && !isNaN($('.video-stream')[0].duration) ? true : false
|
||||
if(videoRunning) {
|
||||
var videoTitle = $('.ytd-video-primary-info-renderer .title').text(),
|
||||
videoAuthor = $("#upload-info .style-scope .ytd-video-owner-renderer").contents().first().html(),
|
||||
videoTimeSeconds = Math.floor($('.video-stream')[0].currentTime),
|
||||
videoDurationSeconds = Math.floor($('.video-stream')[0].duration),
|
||||
videoTimestamps = getTimestamps(videoTimeSeconds, videoDurationSeconds)
|
||||
playback = $('.video-stream')[0].paused ? "paused" : "playing"
|
||||
|
||||
if (playbackChange) eventType = 'playBackChange'; else eventType = 'updateData';
|
||||
|
||||
var playbackBoolean = !$('.video-stream')[0].paused
|
||||
|
||||
var smallImageKey = playbackBoolean ? 'play' : 'pause',
|
||||
smallImageText = playbackBoolean ? chrome.i18n.getMessage('playbackPlaying') : chrome.i18n.getMessage('playbackPaused')
|
||||
|
||||
if(playbackBoolean) {
|
||||
var data = {
|
||||
clientID: '463097721130188830',
|
||||
presenceData: {
|
||||
details: $('<div/>').html(videoTitle).text(),
|
||||
state: $('<div/>').html(videoAuthor).text(),
|
||||
largeImageKey: 'yt_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText,
|
||||
startTimestamp: videoTimestamps[0],
|
||||
endTimestamp: videoTimestamps[1]
|
||||
},
|
||||
currentSeconds: videoTimeSeconds,
|
||||
durationSeconds: videoDurationSeconds,
|
||||
trayTitle: $('<div/>').html(videoTitle).text(),
|
||||
playback: playbackBoolean,
|
||||
service: 'YouTube'
|
||||
}
|
||||
} else {
|
||||
var data = {
|
||||
clientID: '463097721130188830',
|
||||
presenceData: {
|
||||
details: $('<div/>').html(videoTitle).text(),
|
||||
state: $('<div/>').html(videoAuthor).text(),
|
||||
largeImageKey: 'yt_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText,
|
||||
},
|
||||
currentSeconds: videoTimeSeconds,
|
||||
durationSeconds: videoDurationSeconds,
|
||||
trayTitle: $('<div/>').html(videoTitle).text(),
|
||||
playback: playbackBoolean,
|
||||
service: 'YouTube'
|
||||
}
|
||||
}
|
||||
}
|
||||
if(socket.connected) socket.emit(eventType, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Timestamps
|
||||
* @param {Number} videoTime Song Time
|
||||
* @param {Number} videoDuration Song Duration
|
||||
*/
|
||||
function getTimestamps(videoTime, videoDuration) {
|
||||
var startTime = Date.now();
|
||||
var endTime =
|
||||
Math.floor(startTime / 1000) -
|
||||
videoTime +
|
||||
videoDuration;
|
||||
return [Math.floor(startTime/1000), endTime]
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles playback
|
||||
*/
|
||||
function togglePlayback() {
|
||||
//* Toggle playback variable
|
||||
playback = !playback
|
||||
//* Send status to application
|
||||
updateData(playback ? "playing" : "paused")
|
||||
}
|
||||
|
||||
var lastPlayback = false
|
||||
function playbackChange() {
|
||||
if(videoRunning) {
|
||||
if($('.video-stream')[0].paused != lastPlayback) {
|
||||
togglePlayback()
|
||||
lastPlayback = $('.video-stream')[0].paused
|
||||
}
|
||||
}
|
||||
}
|
||||
192
Extension/js/presences/YouTubeMusic.js
Normal file
@@ -0,0 +1,192 @@
|
||||
let musicRunning = false,
|
||||
tabActive = 0,
|
||||
dataUpdaterRunning = false,
|
||||
dataUpdater
|
||||
|
||||
//* Update data and send to application
|
||||
$(document).ready(() => {
|
||||
setInterval(playbackChange, 250)
|
||||
//* Tab Priority
|
||||
setInterval(() => {
|
||||
if(tabActive == 5) {
|
||||
dataUpdaterRunning = false
|
||||
musicRunning = false
|
||||
clearInterval(dataUpdater)
|
||||
}
|
||||
if(tabActive >= 9 && dataUpdaterRunning == false) {
|
||||
dataUpdaterRunning = true
|
||||
dataUpdater = setInterval(updateData, 1000)
|
||||
}
|
||||
if(tabActive > 0) tabActive--
|
||||
}, 500)
|
||||
})
|
||||
|
||||
|
||||
//* Tab Priority
|
||||
chrome.runtime.onMessage.addListener(((message, sender) => {
|
||||
if(tabActive <= 9) tabActive += 2
|
||||
if(tabActive == 0) tabActive = 5
|
||||
}))
|
||||
|
||||
//* Handle Media Keys from sent by application
|
||||
socket.on('mediaKeyHandler', handleMediaKeys)
|
||||
|
||||
/**
|
||||
* Handles Media Keys for easy media control
|
||||
* @param {Object} data Data received from socket
|
||||
*/
|
||||
function handleMediaKeys(data) {
|
||||
//* Check if the data is for YTM & if music is running
|
||||
//* Media control buttons
|
||||
if (musicRunning) {
|
||||
//* Switch cases for playback / Clicks corresponding buttons
|
||||
switch (data.playback) {
|
||||
case "pause":
|
||||
$('.play-pause-button').click()
|
||||
updateData("playPauseTrack")
|
||||
break
|
||||
case "nextTrack":
|
||||
$('.next-button').click()
|
||||
//* Send response back to application
|
||||
updateData("nextTrack")
|
||||
break
|
||||
case "previousTrack":
|
||||
$('.previous-button').click()
|
||||
//* Send response back to application
|
||||
updateData("previousTrack")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Data and send it to the App
|
||||
* @param {String} playbackChange Playback if changed
|
||||
*/
|
||||
function updateData(playbackChange = false) {
|
||||
var eventType
|
||||
musicRunning = $(".title.style-scope.ytmusic-player-bar").html() != "" && $('.video-stream')[0] != undefined && !isNaN($('.video-stream')[0].duration) ? true : false
|
||||
if(musicRunning) {
|
||||
var songTitle = $(".title.style-scope.ytmusic-player-bar").html(),
|
||||
songAuthors = getAuthors(),
|
||||
songTimeSeconds = Math.floor($('.video-stream')[0].currentTime),
|
||||
songDurationSeconds = Math.floor($('.video-stream')[0].duration),
|
||||
songTimestamps = getTimestamps(songTimeSeconds, songDurationSeconds)
|
||||
playback = $('.video-stream')[0].paused ? "paused" : "playing",
|
||||
songAuthorsString = null;
|
||||
|
||||
if (playbackChange) eventType = 'playBackChange'; else eventType = 'updateData';
|
||||
|
||||
songAuthors.forEach((author, index, authors) => {
|
||||
if (index == 0)
|
||||
songAuthorsString = author;
|
||||
else if (index < authors.length - 2)
|
||||
songAuthorsString = songAuthorsString + ", " + author;
|
||||
else if (index < authors.length - 1) songAuthorsString = songAuthorsString + " and " + author;
|
||||
else songAuthorsString = songAuthorsString + " • " + author;
|
||||
});
|
||||
|
||||
var playbackBoolean = !$('.video-stream')[0].paused
|
||||
|
||||
var smallImageKey = playbackBoolean ? 'play' : 'pause',
|
||||
smallImageText = playbackBoolean ? chrome.i18n.getMessage('playbackPlaying') : chrome.i18n.getMessage('playbackPaused')
|
||||
|
||||
if(playbackBoolean) {
|
||||
var data = {
|
||||
clientID: '463151177836658699',
|
||||
presenceData: {
|
||||
details: $('<div/>').html(songTitle).text(),
|
||||
state: $('<div/>').html(songAuthorsString).text(),
|
||||
largeImageKey: 'ytm_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText,
|
||||
startTimestamp: songTimestamps[0],
|
||||
endTimestamp: songTimestamps[1]
|
||||
},
|
||||
currentSeconds: songTimeSeconds,
|
||||
durationSeconds: songDurationSeconds,
|
||||
trayTitle: $('<div/>').html(songTitle).text(),
|
||||
playback: playbackBoolean,
|
||||
service: 'YouTube Music'
|
||||
}
|
||||
} else {
|
||||
var data = {
|
||||
clientID: '463151177836658699',
|
||||
presenceData: {
|
||||
details: $('<div/>').html(songTitle).text(),
|
||||
state: $('<div/>').html(songAuthorsString).text(),
|
||||
largeImageKey: 'ytm_lg',
|
||||
largeImageText: chrome.runtime.getManifest().name + ' V' + chrome.runtime.getManifest().version,
|
||||
smallImageKey: smallImageKey,
|
||||
smallImageText: smallImageText
|
||||
},
|
||||
currentSeconds: songTimeSeconds,
|
||||
durationSeconds: songDurationSeconds,
|
||||
trayTitle: $('<div/>').html(songTitle).text(),
|
||||
playback: playbackBoolean,
|
||||
service: 'YouTube Music'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//* If socket connection, send data
|
||||
if(socket.connected) socket.emit(eventType, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authors of Song
|
||||
*/
|
||||
function getAuthors() {
|
||||
var songAuthors = []
|
||||
//* Extract authors as array
|
||||
$(".byline.ytmusic-player-bar").contents().each(function (index, item) {
|
||||
if (item.classList != undefined) {
|
||||
if (item.classList.contains("yt-simple-endpoint") == true) {
|
||||
songAuthors.push(item.innerHTML)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//* If no authors found in previous method use this
|
||||
if (songAuthors.length == 0 || songAuthors.length == 1) {
|
||||
//* Clear old list
|
||||
songAuthors = []
|
||||
songAuthors.push($(".byline.ytmusic-player-bar").contents().first().text())
|
||||
}
|
||||
return songAuthors
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Timestamps
|
||||
* @param {Number} songTime Song Time
|
||||
* @param {Number} songDuration Song Duration
|
||||
*/
|
||||
function getTimestamps(songTime, songDuration) {
|
||||
var startTime = Date.now();
|
||||
var endTime =
|
||||
Math.floor(startTime / 1000) -
|
||||
songTime +
|
||||
songDuration;
|
||||
return [Math.floor(startTime/1000), endTime]
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles playback
|
||||
*/
|
||||
function togglePlayback() {
|
||||
//* Toggle playback variable
|
||||
playback = !playback
|
||||
//* Send status to application
|
||||
updateData(playback ? "playing" : "paused")
|
||||
}
|
||||
|
||||
var lastPlayback = false
|
||||
function playbackChange() {
|
||||
if(musicRunning) {
|
||||
if($('.video-stream')[0].paused != lastPlayback) {
|
||||
togglePlayback()
|
||||
lastPlayback = $('.video-stream')[0].paused
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Extension/js/updated.js
Normal file
@@ -0,0 +1,27 @@
|
||||
document.getElementById('version').innerHTML = 'V' + chrome.runtime.getManifest().version
|
||||
document.getElementById('updatedYTPUpdated').innerHTML = chrome.i18n.getMessage("updatedYTPUpdated")
|
||||
document.getElementById('updatedWhatsNew').innerHTML = chrome.i18n.getMessage("updatedWhatsNew")
|
||||
|
||||
var hasNextChanged = true,
|
||||
index = 0
|
||||
while(hasNextChanged) {
|
||||
if(chrome.i18n.getMessage("updatedAdded" + index) != "") {
|
||||
var item = document.getElementById('updatedWhatsNewList').appendChild(document.createElement('li'))
|
||||
item.innerHTML = chrome.i18n.getMessage("updatedAdded" + index)
|
||||
} else hasNextChanged = false;
|
||||
index++
|
||||
}
|
||||
|
||||
document.getElementById('updatedWhatChanged').innerHTML = chrome.i18n.getMessage("updatedWhatChanged")
|
||||
|
||||
var hasNextChanged = true,
|
||||
index = 0
|
||||
while(hasNextChanged) {
|
||||
if(chrome.i18n.getMessage("updatedChanged" + index) != "") {
|
||||
var item = document.getElementById('updatedWhatChangedList').appendChild(document.createElement('li'))
|
||||
item.innerHTML = chrome.i18n.getMessage("updatedChanged" + index)
|
||||
} else hasNextChanged = false;
|
||||
index++
|
||||
}
|
||||
|
||||
document.getElementById('installedSupportMe').innerHTML = chrome.i18n.getMessage("installedSupportMe")
|
||||
7
Extension/js/util/socket.io-2.1.1.min.js
vendored
Normal file
27
Extension/js/util/socketConnector.js
Normal file
@@ -0,0 +1,27 @@
|
||||
//* Create socket connection to application
|
||||
var socket = io.connect('http://localhost:3020/');
|
||||
|
||||
//* Log when connected
|
||||
socket.on('connect', socketConnect)
|
||||
socket.on('disconnect', socketDisconnect)
|
||||
|
||||
function socketConnect() {
|
||||
console.log(chrome.runtime.getManifest().name + ': %c' + chrome.i18n.getMessage('connected'), "color: green; font-weight: 700")
|
||||
if(sessionStorage['ytpconnected'] == null || sessionStorage['ytpconnected'] == 'false') {
|
||||
sessionStorage['ytpconnected'] = 'true'
|
||||
insertConnectionInfo(chrome.i18n.getMessage("connected"))
|
||||
}
|
||||
}
|
||||
|
||||
function socketDisconnect() {
|
||||
console.log(chrome.runtime.getManifest().name + ': %c' + chrome.i18n.getMessage('disconnected'), "color: red; font-weight: 700")
|
||||
sessionStorage['ytpconnected'] = 'false'
|
||||
insertConnectionInfo(chrome.i18n.getMessage("disconnected"))
|
||||
}
|
||||
|
||||
function insertConnectionInfo(message) {
|
||||
$('<div id="ytp-connectinfo"><img draggable="false" src="https://raw.githubusercontent.com/Timeraa/YT-Presence/master/icon.png"><h1>' + chrome.runtime.getManifest().name + '</h1><h2>' + message + '</h2></div>').appendTo('body')
|
||||
setTimeout(() => {
|
||||
$('#ytp-connectinfo').remove()
|
||||
}, 5*1000)
|
||||
}
|
||||
@@ -1,29 +1,75 @@
|
||||
{
|
||||
"name": "YT Presence",
|
||||
"version": "0.3",
|
||||
"description": "Discord Rich Presence for YouTube and YouTube Music.",
|
||||
"manifest_version": 3,
|
||||
"name": "PreMiD",
|
||||
"author": "Timeraa",
|
||||
"version": "1.2",
|
||||
"description": "__MSG_appDesc__",
|
||||
"manifest_version": 2,
|
||||
"default_locale": "en",
|
||||
"icons": {
|
||||
"2024": "images/icon.png"
|
||||
"2024": "icon.png"
|
||||
},
|
||||
"background": {
|
||||
"scripts": ["jquery-3.3.1.min.js", "background.js"],
|
||||
"persistent": true
|
||||
"scripts": ["js/util/socket.io-2.1.1.min.js", "js/background.js"],
|
||||
"presistent": false
|
||||
},
|
||||
"browser_action": {
|
||||
"default_popup": "html/popup/popup.html",
|
||||
"default_icon": {
|
||||
"2024": "images/icon.png"
|
||||
"2024": "icon.png"
|
||||
}
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"js": ["jquery-3.3.1.min.js", "handleYTM.js"],
|
||||
"js": [
|
||||
"js/util/jquery-3.3.1.min.js",
|
||||
"js/util/socket.io-2.1.1.min.js",
|
||||
"js/util/socketConnector.js"
|
||||
],
|
||||
"css": ["css/connect.css"],
|
||||
"matches": [
|
||||
"https://www.youtube.com/*",
|
||||
"https://music.youtube.com/*",
|
||||
"https://*.netflix.com/*",
|
||||
"https://soundcloud.com/*",
|
||||
"https://*.twitch.tv/*",
|
||||
"https://kissanime.ac/*",
|
||||
"https://kissanime.ru/*",
|
||||
"https://jkanime.net/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"js": ["js/presences/YouTubeMusic.js"],
|
||||
"matches": ["https://music.youtube.com/*"]
|
||||
},
|
||||
{
|
||||
"js": ["jquery-3.3.1.min.js", "handleYT.js"],
|
||||
"js": ["js/presences/YouTube.js"],
|
||||
"matches": ["https://www.youtube.com/*"]
|
||||
},
|
||||
{
|
||||
"js": ["js/presences/Netflix.js"],
|
||||
"matches": ["https://*.netflix.com/*"]
|
||||
},
|
||||
{
|
||||
"js": ["js/presences/SoundCloud.js"],
|
||||
"matches": ["https://*.soundcloud.com/*"]
|
||||
},
|
||||
{
|
||||
"js": ["js/presences/Twitch.js"],
|
||||
"matches": ["https://*.twitch.tv/*"]
|
||||
},
|
||||
{
|
||||
"js": ["js/presences/KissAnime.js"],
|
||||
"matches": ["https://kissanime.ac/*", "https://kissanime.ru/*"]
|
||||
},
|
||||
{
|
||||
"js": ["js/presences/JKAnime.js"],
|
||||
"matches": ["https://jkanime.net/*"]
|
||||
}
|
||||
],
|
||||
"permissions": ["http://localhost/*", "tabs"]
|
||||
"permissions": [
|
||||
"http://localhost:3020/",
|
||||
"tabs",
|
||||
"storage",
|
||||
"declarativeContent"
|
||||
]
|
||||
}
|
||||
|
||||
198
README.md
@@ -1,58 +1,97 @@
|
||||
## 
|
||||
##  [](https://discord.gg/Kw7WaYn)
|
||||
|
||||
# <img src="icon.png" width="20" draggable="false"><b> </b>YouTube Presence · Watcha watching there? 👀
|
||||
# <img src="gitassets/premid.webp" width="24px" draggable="false"><b> </b>PreMiD · Discord Rich Presence for your Media!
|
||||
|
||||
_Show your current YouTube video/song in your Discord profile_
|
||||
<a target="_blank" href="https://discord.gg/Kw7WaYn" title="Join our Discord!">
|
||||
<img src="gitassets/discord.svg" height="50px" draggable="false" alt="Join my Discord!">
|
||||
</a>
|
||||
<a target="_blank" href="https://www.patreon.com/bePatron?u=4610890" data-patreon-widget-type="become-patron-button"><img src="gitassets/patreonBTN.png" draggable="false" height="50px" alt="Support me on Patreon!"></a>
|
||||
<a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZU8Q766ACS2WS&lc=US"><img src="gitassets/PayPal.svg" height="50px" draggable="false" alt="PayPal"></a>
|
||||
|
||||
## Table of contents
|
||||
# About
|
||||
|
||||
- [Table of contents](#table-of-contents)
|
||||
- [Installing the Extension](#installing-the-extension)
|
||||
- [Installing the Application](#installing-the-application)
|
||||
- Mac OS
|
||||
- Windows
|
||||
- [FAQ](#faq-·-frequently-asked-questions)
|
||||
- Why can't i install it on the Chrome Web Store?
|
||||
- Is this project up to date?
|
||||
- Will this project stay free?
|
||||
## Summary
|
||||
|
||||
## Installing the Extension
|
||||
**PreMiD** is a simple, configurable utility that allows you to show what you're watching/listening in your Discord **now playing status**. It supports [many different platforms](#support), and will support multiple users watching the same content simultaneously in an upcoming update.
|
||||
|
||||
## Features
|
||||
|
||||
- Integrates with Discord's official Rich Presence API library.
|
||||
- Supports your keyboard's **Media Control** function keys.
|
||||
- Automatically clears your current presence after 1 minute of inactivity.
|
||||
- Supports **YouTube, YouTube Music, Netflix, SoundCloud, JKAnime, KissAnime** and many more to come.
|
||||
- _Watch parties and more are coming soon!_
|
||||
|
||||
# Table of contents
|
||||
|
||||
- [About](#about)
|
||||
- [Summary](#summary)
|
||||
- [Features](#features)
|
||||
- [Support](#support)
|
||||
- [Operating Systems](#operating-systems)
|
||||
- [Browsers](#browsers)
|
||||
- [Services](#services)
|
||||
- [Installation](#installation)
|
||||
- [Extension](#extension)
|
||||
- Chrome
|
||||
- Opera
|
||||
- [Application](#application)
|
||||
- Mac OS
|
||||
- Windows
|
||||
|
||||
# Support
|
||||
|
||||
### **Operating Systems**
|
||||
|
||||
- Windows
|
||||
- Mac OS
|
||||
|
||||
### **Browsers**
|
||||
|
||||
- Chrome
|
||||
- Opera
|
||||
|
||||
### **Services**
|
||||
|
||||
- YouTube
|
||||
- YouTube Music
|
||||
- Netflix
|
||||
- SoundCloud
|
||||
- Twitch
|
||||
- JKAnime
|
||||
- KissAnime
|
||||
|
||||
One missing? Open an [Issue](https://github.com/Timeraa/PreMiD/issues/new?template=feature_request.md)!
|
||||
|
||||
# Installation
|
||||
|
||||
## Extension
|
||||
|
||||
<details>
|
||||
<summary><b><u>Installing the Chrome extension</u></b> (Click to expand)</summary>
|
||||
<h1>Chrome extension installation</h1>
|
||||
<h1>Chrome Extension Installation</h1>
|
||||
<ol>
|
||||
<li>Download the latest version of the <a href="https://github.com/Timeraa/YT-Presence/releases/latest">extension</a>
|
||||
<li>Click <a href="https://chrome.google.com/webstore/detail/yt-presence/agjnjboanicjcpenljmaaigopkgdnihi">this</a> link</li>
|
||||
</li>
|
||||
<li>Extract the downloaded <b>.zip</b> file</li>
|
||||
<li>Open Chrome</li>
|
||||
<li>Go to <a href="chrome://extensions/">chrome://extensions/</a></li>
|
||||
<li>Turn on <b>Developer mode</b><br>
|
||||
<img src="developerMode.png">
|
||||
</li>
|
||||
<li>Click "<b>Load unpacked extension</b>"<br>
|
||||
<img src="loadUnpackedExtension.png">
|
||||
</li>
|
||||
<li>Load the extracted <b>Extension</b> folder</li>
|
||||
<li>Install the <a href="#installing-the-application">application</a></li>
|
||||
<li>Click "add to Chrome"</li>
|
||||
<li>Install the <a href="#application">application</a></li>
|
||||
</ol>
|
||||
</details>
|
||||
<details>
|
||||
<summary><b><u>Installing the Opera extension</u></b> (Click to expand)</summary>
|
||||
<h1>Opera extension installation</h1>
|
||||
<h1>Opera Extension Installation</h1>
|
||||
<ol>
|
||||
<li>Download the latest version of the <a href="https://github.com/Timeraa/YT-Presence/releases/latest">extension</a>
|
||||
</li>
|
||||
<li>Extract the downloaded <b>.zip</b> file</li>
|
||||
<li>Open Opera</li>
|
||||
<li>Go to <a href="chrome://extensions/">chrome://extensions/</a></li>
|
||||
<li>Drag and drop the extension's folder on the page<br>
|
||||
<li>Load the extracted <b>Extension</b> folder</li>
|
||||
<li>Install the <a href="#installing-the-application">application</a></li>
|
||||
<li>Drag and drop the Folder <b>"Extension"</b> on the page<br>
|
||||
<li>Install the <a href="#application">application</a></li>
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
## Installing the Application
|
||||
## Application
|
||||
|
||||
<details>
|
||||
<summary><b><u>Mac OS</u></b> (Click to expand)</summary>
|
||||
@@ -60,12 +99,12 @@ _Show your current YouTube video/song in your Discord profile_
|
||||
<ol>
|
||||
<li>Download the latest version of the <a href="https://github.com/Timeraa/YT-Presence/releases/latest">application</a>
|
||||
</li>
|
||||
<li>Extract the downloaded <b>.zip</b> file</li>
|
||||
<li>Open the extracted folder and run the <b>.dmg</b> file</li>
|
||||
<li>Drag <b>YT Presence</b> Into your <b>Applications</b> Folder</li>
|
||||
<li>Open your Launchpad</li>
|
||||
<li>Open <b>YT Presence</b></li>
|
||||
<li>Enjoy!</li>
|
||||
<li>Open the downloaded <b>.dmg</b> file</li>
|
||||
<li>Drag <b>PreMiD</b> Into your <b>Applications</b> Folder</li>
|
||||
<li>Open your Launchpad or press F4</li>
|
||||
<li>Open <b>PreMiD</b></li>
|
||||
<li>Press <b>"Allow"</b> if a window pops up</li>
|
||||
<li>Install <a href="#extension">extension</a> if not already</li>
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
@@ -73,28 +112,71 @@ _Show your current YouTube video/song in your Discord profile_
|
||||
<summary><b><u>Windows</u></b> (Click to expand)</summary>
|
||||
<h1>Installation on Windows</h1>
|
||||
<ol>
|
||||
<li>Extract the downloaded <b>.zip</b> file</li>
|
||||
<li>Open extracted folder and run <b>YT Presence.exe</b></li>
|
||||
<li>Download the latest installer from <a href="https://github.com/Timeraa/YT-Presence/releases/">here</a></li>
|
||||
<li>Open the downloaded <b>.exe</b> installer</li>
|
||||
<li>If SmartScreen comes up press more informations then press run anyways. (It's not a virus, I promise.)</li>
|
||||
<li>YouTube Presence should install itself and start automatically. (You can tell by looking at the taskbar.)</li>
|
||||
<li>Install the <a href="#extension">extension</a>, if you haven't already.</li>
|
||||
</ol>
|
||||
</details>
|
||||
<br>
|
||||
|
||||
**Note: The windows version does not have an installer at the moment. I am working hard on packaging the application into an installer. Please be patient. Thanks**
|
||||
|
||||
## FAQ · Frequently Asked Questions
|
||||
|
||||
> ## Why can't i install the extension on the **Chrome Web Store**?<br>
|
||||
|
||||
- Because i need to activate my google account as a Developer account but that requires **5$** and i am not paying it until i receive donations for this Project. <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZU8Q766ACS2WS&lc=US">Donate here</a>
|
||||
|
||||
> ## Is this project still up to date?<br>
|
||||
|
||||
- Yes! I use and work on this program and extension almost everyday!<br>There are currently no plans on discontinuing this Project.
|
||||
|
||||
> ## Will this project stay free?<br>
|
||||
|
||||
- Of course! Its open source! But i would highly appreciate a little bit of Money to activate the Google Developer Account so that i can put the Chrome extension on the Chrome Web store. And it would help me to get the money needed for future plans like a **Driving license** 😎<br><br><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZU8Q766ACS2WS&lc=US">Donate here</a>
|
||||
|
||||
---
|
||||
|
||||
### YT Presence version 0.3 · By Timeraa
|
||||
<h1 style="text-align: center;">Creator</h1>
|
||||
<div style="margin: 5px; width: 100px; display: inline-block;">
|
||||
<img draggable="false" src="gitassets/timeraa.png" style="border-radius: 50%;" width="100px">
|
||||
<h2 style="text-align: center; font-weight: 700; margin: 0;">Timeraa</h2>
|
||||
</div>
|
||||
|
||||
<h1 style="text-align: center;">Admin & Translation Manager</h1>
|
||||
<div style="margin: 5px; width: 100px; display: inline-block;">
|
||||
<img draggable="false" src="gitassets/fruxh.png" style="border-radius: 50%;" width="100px">
|
||||
<h2 style="text-align: center; font-weight: 700; margin: 0;">Fruxh</h2>
|
||||
</div>
|
||||
|
||||
<h1 style="text-align: center;">Patrons \ Donators</h1>
|
||||
<div style="margin: 5px; width: 100px; display: inline-block;">
|
||||
<img draggable="false" src="gitassets/fruxh.png" style="border-radius: 50%;" width="100px">
|
||||
<h2 style="text-align: center; font-weight: 700; margin: 0;">Fruxh</h2>
|
||||
<h3 style="text-align: center; font-weight: 700;margin: 0;">Patron</h3>
|
||||
</div>
|
||||
<div style="margin: 5px; width: 100px; display: inline-block;">
|
||||
<img draggable="false" src="gitassets/UMU.png" style="border-radius: 50%;" width="100px">
|
||||
<h2 style="text-align: center; font-weight: 700; margin: 0;">UMU</h2>
|
||||
<h3 style="text-align: center; font-weight: 700;margin: 0;">Patron</h3>
|
||||
</div>
|
||||
<div style="margin: 5px; width: 100px; display: inline-block;">
|
||||
<img draggable="false" src="gitassets/paz.png" style="border-radius: 50%;" width="100px">
|
||||
<h2 style="text-align: center; font-weight: 700; margin: 0;">Paz</h2>
|
||||
<h3 style="text-align: center; font-weight: 700;margin: 0;">Paypal</h3>
|
||||
</div>
|
||||
|
||||
<h1 style="text-align: center;">Translators</h1>
|
||||
<div style="margin: 5px; width: 100px; display: inline-block;">
|
||||
<img draggable="false" src="gitassets/timeraa.png" style="border-radius: 50%;" width="100px">
|
||||
<h2 style="text-align: center; font-weight: 700; margin: 0;">Timeraa</h2>
|
||||
</div>
|
||||
<div style="margin: 5px; width: 100px; display: inline-block;">
|
||||
<img draggable="false" src="gitassets/fruxh.png" style="border-radius: 50%;" width="100px">
|
||||
<h2 style="text-align: center; font-weight: 700; margin: 0;">Fruxh</h2>
|
||||
</div>
|
||||
<div style="margin: 5px; width: 100px; display: inline-block;">
|
||||
<img draggable="false" src="gitassets/restrike.png" style="border-radius: 50%;" width="100px">
|
||||
<h2 style="text-align: center; font-weight: 700; margin: 0;">Restrike</h2>
|
||||
</div>
|
||||
<div style="margin: 5px; width: 100px; display: inline-block;">
|
||||
<img draggable="false" src="gitassets/xiRDX.gif" style="border-radius: 50%;" width="100px">
|
||||
<h2 style="text-align: center; font-weight: 700; margin: 0;">2dward.</h2>
|
||||
</div>
|
||||
<div style="margin: 5px; width: 100px; display: inline-block;">
|
||||
<img draggable="false" src="gitassets/ufo.png" style="border-radius: 50%;" width="100px">
|
||||
<h2 style="text-align: center; font-weight: 700; margin: 0;">Ufo</h2>
|
||||
</div>
|
||||
<div style="margin: 5px; width: 100px; display: inline-block;">
|
||||
<img draggable="false" src="gitassets/VerifyBot.png" style="border-radius: 50%;" width="100px">
|
||||
<h2 style="text-align: center; font-weight: 700; margin: 0;">VerifyBot</h2>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
### PreMiD - Discord Rich Presence for your Media!
|
||||
|
||||
BIN
appIcon.icns
BIN
appIcon.ico
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 21 KiB |
@@ -1,9 +0,0 @@
|
||||
var electronInstaller = require('electron-winstaller');
|
||||
|
||||
resultPromise = electronInstaller.createWindowsInstaller({
|
||||
appDirectory: '/out/YT Presence-win32-64x',
|
||||
outputDirectory: '/dist/installerWindows',
|
||||
authors: 'Timeraa',
|
||||
});
|
||||
|
||||
resultPromise.then(() => console.log("It worked!"), (e) => console.log(`No dice: ${e.message}`));
|
||||
|
Before Width: | Height: | Size: 5.8 KiB |
BIN
dmg-background.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
@@ -1,15 +0,0 @@
|
||||
// config.forge.js
|
||||
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
packagerConfig: {
|
||||
appBundleId: "eu.Timeraa.YTPresence",
|
||||
icon: path.resolve(__dirname, 'appIcon.icns')
|
||||
},
|
||||
make_targets: {
|
||||
win32: ["squirrel"], // An array of win32 make targets
|
||||
darwin: ["dmg"], // An array of darwin make targets
|
||||
linux: ["deb", "rpm", "flatpak", "snap"] // An array of linux make targets
|
||||
}
|
||||
}
|
||||
55
gitassets/PayPal.svg
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="124px" height="33px" viewBox="0 0 124 33" enable-background="new 0 0 124 33" xml:space="preserve">
|
||||
<path fill="#253B80" d="M46.211,6.749h-6.839c-0.468,0-0.866,0.34-0.939,0.802l-2.766,17.537c-0.055,0.346,0.213,0.658,0.564,0.658
|
||||
h3.265c0.468,0,0.866-0.34,0.939-0.803l0.746-4.73c0.072-0.463,0.471-0.803,0.938-0.803h2.165c4.505,0,7.105-2.18,7.784-6.5
|
||||
c0.306-1.89,0.013-3.375-0.872-4.415C50.224,7.353,48.5,6.749,46.211,6.749z M47,13.154c-0.374,2.454-2.249,2.454-4.062,2.454
|
||||
h-1.032l0.724-4.583c0.043-0.277,0.283-0.481,0.563-0.481h0.473c1.235,0,2.4,0,3.002,0.704C47.027,11.668,47.137,12.292,47,13.154z"
|
||||
/>
|
||||
<path fill="#253B80" d="M66.654,13.075h-3.275c-0.279,0-0.52,0.204-0.563,0.481l-0.145,0.916l-0.229-0.332
|
||||
c-0.709-1.029-2.29-1.373-3.868-1.373c-3.619,0-6.71,2.741-7.312,6.586c-0.313,1.918,0.132,3.752,1.22,5.031
|
||||
c0.998,1.176,2.426,1.666,4.125,1.666c2.916,0,4.533-1.875,4.533-1.875l-0.146,0.91c-0.055,0.348,0.213,0.66,0.562,0.66h2.95
|
||||
c0.469,0,0.865-0.34,0.939-0.803l1.77-11.209C67.271,13.388,67.004,13.075,66.654,13.075z M62.089,19.449
|
||||
c-0.316,1.871-1.801,3.127-3.695,3.127c-0.951,0-1.711-0.305-2.199-0.883c-0.484-0.574-0.668-1.391-0.514-2.301
|
||||
c0.295-1.855,1.805-3.152,3.67-3.152c0.93,0,1.686,0.309,2.184,0.892C62.034,17.721,62.232,18.543,62.089,19.449z"/>
|
||||
<path fill="#253B80" d="M84.096,13.075h-3.291c-0.314,0-0.609,0.156-0.787,0.417l-4.539,6.686l-1.924-6.425
|
||||
c-0.121-0.402-0.492-0.678-0.912-0.678h-3.234c-0.393,0-0.666,0.384-0.541,0.754l3.625,10.638l-3.408,4.811
|
||||
c-0.268,0.379,0.002,0.9,0.465,0.9h3.287c0.312,0,0.604-0.152,0.781-0.408L84.564,13.97C84.826,13.592,84.557,13.075,84.096,13.075z
|
||||
"/>
|
||||
<path fill="#179BD7" d="M94.992,6.749h-6.84c-0.467,0-0.865,0.34-0.938,0.802l-2.766,17.537c-0.055,0.346,0.213,0.658,0.562,0.658
|
||||
h3.51c0.326,0,0.605-0.238,0.656-0.562l0.785-4.971c0.072-0.463,0.471-0.803,0.938-0.803h2.164c4.506,0,7.105-2.18,7.785-6.5
|
||||
c0.307-1.89,0.012-3.375-0.873-4.415C99.004,7.353,97.281,6.749,94.992,6.749z M95.781,13.154c-0.373,2.454-2.248,2.454-4.062,2.454
|
||||
h-1.031l0.725-4.583c0.043-0.277,0.281-0.481,0.562-0.481h0.473c1.234,0,2.4,0,3.002,0.704
|
||||
C95.809,11.668,95.918,12.292,95.781,13.154z"/>
|
||||
<path fill="#179BD7" d="M115.434,13.075h-3.273c-0.281,0-0.52,0.204-0.562,0.481l-0.145,0.916l-0.23-0.332
|
||||
c-0.709-1.029-2.289-1.373-3.867-1.373c-3.619,0-6.709,2.741-7.311,6.586c-0.312,1.918,0.131,3.752,1.219,5.031
|
||||
c1,1.176,2.426,1.666,4.125,1.666c2.916,0,4.533-1.875,4.533-1.875l-0.146,0.91c-0.055,0.348,0.213,0.66,0.564,0.66h2.949
|
||||
c0.467,0,0.865-0.34,0.938-0.803l1.771-11.209C116.053,13.388,115.785,13.075,115.434,13.075z M110.869,19.449
|
||||
c-0.314,1.871-1.801,3.127-3.695,3.127c-0.949,0-1.711-0.305-2.199-0.883c-0.484-0.574-0.666-1.391-0.514-2.301
|
||||
c0.297-1.855,1.805-3.152,3.67-3.152c0.93,0,1.686,0.309,2.184,0.892C110.816,17.721,111.014,18.543,110.869,19.449z"/>
|
||||
<path fill="#179BD7" d="M119.295,7.23l-2.807,17.858c-0.055,0.346,0.213,0.658,0.562,0.658h2.822c0.469,0,0.867-0.34,0.939-0.803
|
||||
l2.768-17.536c0.055-0.346-0.213-0.659-0.562-0.659h-3.16C119.578,6.749,119.338,6.953,119.295,7.23z"/>
|
||||
<path fill="#253B80" d="M7.266,29.154l0.523-3.322l-1.165-0.027H1.061L4.927,1.292C4.939,1.218,4.978,1.149,5.035,1.1
|
||||
c0.057-0.049,0.13-0.076,0.206-0.076h9.38c3.114,0,5.263,0.648,6.385,1.927c0.526,0.6,0.861,1.227,1.023,1.917
|
||||
c0.17,0.724,0.173,1.589,0.007,2.644l-0.012,0.077v0.676l0.526,0.298c0.443,0.235,0.795,0.504,1.065,0.812
|
||||
c0.45,0.513,0.741,1.165,0.864,1.938c0.127,0.795,0.085,1.741-0.123,2.812c-0.24,1.232-0.628,2.305-1.152,3.183
|
||||
c-0.482,0.809-1.096,1.48-1.825,2c-0.696,0.494-1.523,0.869-2.458,1.109c-0.906,0.236-1.939,0.355-3.072,0.355h-0.73
|
||||
c-0.522,0-1.029,0.188-1.427,0.525c-0.399,0.344-0.663,0.814-0.744,1.328l-0.055,0.299l-0.924,5.855l-0.042,0.215
|
||||
c-0.011,0.068-0.03,0.102-0.058,0.125c-0.025,0.021-0.061,0.035-0.096,0.035H7.266z"/>
|
||||
<path fill="#179BD7" d="M23.048,7.667L23.048,7.667L23.048,7.667c-0.028,0.179-0.06,0.362-0.096,0.55
|
||||
c-1.237,6.351-5.469,8.545-10.874,8.545H9.326c-0.661,0-1.218,0.48-1.321,1.132l0,0l0,0L6.596,26.83l-0.399,2.533
|
||||
c-0.067,0.428,0.263,0.814,0.695,0.814h4.881c0.578,0,1.069-0.42,1.16-0.99l0.048-0.248l0.919-5.832l0.059-0.32
|
||||
c0.09-0.572,0.582-0.992,1.16-0.992h0.73c4.729,0,8.431-1.92,9.513-7.476c0.452-2.321,0.218-4.259-0.978-5.622
|
||||
C24.022,8.286,23.573,7.945,23.048,7.667z"/>
|
||||
<path fill="#222D65" d="M21.754,7.151c-0.189-0.055-0.384-0.105-0.584-0.15c-0.201-0.044-0.407-0.083-0.619-0.117
|
||||
c-0.742-0.12-1.555-0.177-2.426-0.177h-7.352c-0.181,0-0.353,0.041-0.507,0.115C9.927,6.985,9.675,7.306,9.614,7.699L8.05,17.605
|
||||
l-0.045,0.289c0.103-0.652,0.66-1.132,1.321-1.132h2.752c5.405,0,9.637-2.195,10.874-8.545c0.037-0.188,0.068-0.371,0.096-0.55
|
||||
c-0.313-0.166-0.652-0.308-1.017-0.429C21.941,7.208,21.848,7.179,21.754,7.151z"/>
|
||||
<path fill="#253B80" d="M9.614,7.699c0.061-0.393,0.313-0.714,0.652-0.876c0.155-0.074,0.326-0.115,0.507-0.115h7.352
|
||||
c0.871,0,1.684,0.057,2.426,0.177c0.212,0.034,0.418,0.073,0.619,0.117c0.2,0.045,0.395,0.095,0.584,0.15
|
||||
c0.094,0.028,0.187,0.057,0.278,0.086c0.365,0.121,0.704,0.264,1.017,0.429c0.368-2.347-0.003-3.945-1.272-5.392
|
||||
C20.378,0.682,17.853,0,14.622,0h-9.38c-0.66,0-1.223,0.48-1.325,1.133L0.01,25.898c-0.077,0.49,0.301,0.932,0.795,0.932h5.791
|
||||
l1.454-9.225L9.614,7.699z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.5 KiB |
BIN
gitassets/UMU.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
gitassets/VerifyBot.png
Executable file
|
After Width: | Height: | Size: 129 KiB |
1
gitassets/discord.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 272.1"><style>.st0{fill:#7289DA;}</style><path class="st0" d="M142.8 120.1c-5.7 0-10.2 4.9-10.2 11s4.6 11 10.2 11c5.7 0 10.2-4.9 10.2-11s-4.6-11-10.2-11zM106.3 120.1c-5.7 0-10.2 4.9-10.2 11s4.6 11 10.2 11c5.7 0 10.2-4.9 10.2-11 .1-6.1-4.5-11-10.2-11z"/><path class="st0" d="M191.4 36.9h-134c-11.3 0-20.5 9.2-20.5 20.5v134c0 11.3 9.2 20.5 20.5 20.5h113.4l-5.3-18.3 12.8 11.8 12.1 11.1 21.6 18.7V57.4c-.1-11.3-9.3-20.5-20.6-20.5zm-38.6 129.5s-3.6-4.3-6.6-8c13.1-3.7 18.1-11.8 18.1-11.8-4.1 2.7-8 4.6-11.5 5.9-5 2.1-9.8 3.4-14.5 4.3-9.6 1.8-18.4 1.3-25.9-.1-5.7-1.1-10.6-2.6-14.7-4.3-2.3-.9-4.8-2-7.3-3.4-.3-.2-.6-.3-.9-.5-.2-.1-.3-.2-.4-.2-1.8-1-2.8-1.7-2.8-1.7s4.8 7.9 17.5 11.7c-3 3.8-6.7 8.2-6.7 8.2-22.1-.7-30.5-15.1-30.5-15.1 0-31.9 14.4-57.8 14.4-57.8 14.4-10.7 28-10.4 28-10.4l1 1.2c-18 5.1-26.2 13-26.2 13s2.2-1.2 5.9-2.8c10.7-4.7 19.2-5.9 22.7-6.3.6-.1 1.1-.2 1.7-.2 6.1-.8 13-1 20.2-.2 9.5 1.1 19.7 3.9 30.1 9.5 0 0-7.9-7.5-24.9-12.6l1.4-1.6s13.7-.3 28 10.4c0 0 14.4 25.9 14.4 57.8 0-.1-8.4 14.3-30.5 15zM303.8 79.7h-33.2V117l22.1 19.9v-36.2h11.8c7.5 0 11.2 3.6 11.2 9.4v27.7c0 5.8-3.5 9.7-11.2 9.7h-34v21.1h33.2c17.8.1 34.5-8.8 34.5-29.2v-29.8c.1-20.8-16.6-29.9-34.4-29.9zm174 59.7v-30.6c0-11 19.8-13.5 25.8-2.5l18.3-7.4c-7.2-15.8-20.3-20.4-31.2-20.4-17.8 0-35.4 10.3-35.4 30.3v30.6c0 20.2 17.6 30.3 35 30.3 11.2 0 24.6-5.5 32-19.9l-19.6-9c-4.8 12.3-24.9 9.3-24.9-1.4zM417.3 113c-6.9-1.5-11.5-4-11.8-8.3.4-10.3 16.3-10.7 25.6-.8l14.7-11.3c-9.2-11.2-19.6-14.2-30.3-14.2-16.3 0-32.1 9.2-32.1 26.6 0 16.9 13 26 27.3 28.2 7.3 1 15.4 3.9 15.2 8.9-.6 9.5-20.2 9-29.1-1.8l-14.2 13.3c8.3 10.7 19.6 16.1 30.2 16.1 16.3 0 34.4-9.4 35.1-26.6 1-21.7-14.8-27.2-30.6-30.1zm-67 55.5h22.4V79.7h-22.4v88.8zM728 79.7h-33.2V117l22.1 19.9v-36.2h11.8c7.5 0 11.2 3.6 11.2 9.4v27.7c0 5.8-3.5 9.7-11.2 9.7h-34v21.1H728c17.8.1 34.5-8.8 34.5-29.2v-29.8c0-20.8-16.7-29.9-34.5-29.9zm-162.9-1.2c-18.4 0-36.7 10-36.7 30.5v30.3c0 20.3 18.4 30.5 36.9 30.5 18.4 0 36.7-10.2 36.7-30.5V109c0-20.4-18.5-30.5-36.9-30.5zm14.4 60.8c0 6.4-7.2 9.7-14.3 9.7-7.2 0-14.4-3.1-14.4-9.7V109c0-6.5 7-10 14-10 7.3 0 14.7 3.1 14.7 10v30.3zM682.4 109c-.5-20.8-14.7-29.2-33-29.2h-35.5v88.8h22.7v-28.2h4l20.6 28.2h28L665 138.1c10.7-3.4 17.4-12.7 17.4-29.1zm-32.6 12h-13.2v-20.3h13.2c14.1 0 14.1 20.3 0 20.3z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
BIN
gitassets/fruxh.png
Executable file
|
After Width: | Height: | Size: 149 KiB |
BIN
gitassets/patreonBTN.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
gitassets/paz.png
Executable file
|
After Width: | Height: | Size: 540 KiB |
BIN
gitassets/premid.webp
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
gitassets/restrike.png
Executable file
|
After Width: | Height: | Size: 500 KiB |
BIN
gitassets/timeraa.png
Executable file
|
After Width: | Height: | Size: 31 KiB |
BIN
gitassets/ufo.png
Executable file
|
After Width: | Height: | Size: 178 KiB |
BIN
gitassets/xiRDX.gif
Executable file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
icon.png
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 18 KiB |
39
installer.js
Normal file
@@ -0,0 +1,39 @@
|
||||
var os = require('os')
|
||||
var os = os.platform()
|
||||
|
||||
var path = require('path')
|
||||
var chalk = require('chalk')
|
||||
|
||||
if(os == 'darwin') {
|
||||
console.log(chalk.yellow("Creating installer for Mac OS..."))
|
||||
var createDMG = require('electron-installer-dmg')
|
||||
|
||||
createDMG({
|
||||
appPath: "./out/PreMiD-darwin-x64/PreMiD.app",
|
||||
name: "PreMiD",
|
||||
background: "./dmg-background.png",
|
||||
icon: "./appIcon.icns",
|
||||
contents: [
|
||||
{ x: 500, y: 250, type: 'link', path: '/Applications'},
|
||||
{ x: 175, y: 250, type: 'file', path: path.join(__dirname, './out/PreMiD-darwin-x64/PreMiD.app')}
|
||||
],
|
||||
out: "./dist/installer/",
|
||||
overwrite: true
|
||||
}, function done(err) {
|
||||
if(err) console.error(err);
|
||||
else console.log(chalk.green("Created installer for Mac OS!"))
|
||||
})
|
||||
} else if(os == "win32") {
|
||||
console.log(chalk.yellow("Creating installer for Windows..."))
|
||||
var electronInstaller = require('electron-winstaller');
|
||||
|
||||
resultPromise = electronInstaller.createWindowsInstaller({
|
||||
appDirectory: './out/PreMiD-win32-x64',
|
||||
outputDirectory: './dist/installer/',
|
||||
exe: './PreMiD.exe',
|
||||
iconUrl: 'https://raw.githubusercontent.com/Timeraa/PreMiD/master/appIcon.ico',
|
||||
noMsi: true
|
||||
});
|
||||
|
||||
resultPromise.then(() => console.log(chalk.green("Created installer for Windows!")), (e) => console.log(`No dice: ${e.message}`));
|
||||
}
|
||||
|
Before Width: | Height: | Size: 16 KiB |
3340
package-lock.json
generated
50
package.json
@@ -1,45 +1,25 @@
|
||||
{
|
||||
"name": "yt-presence",
|
||||
"productName": "YT Presence",
|
||||
"version": "0.3.0",
|
||||
"description": "Show your current YouTube Video / Song in your Discord profile.",
|
||||
"main": "src/index.js",
|
||||
"repository": "Timeraa/YT-Presence",
|
||||
"name": "premid",
|
||||
"productName": "PreMiD",
|
||||
"version": "1.2.0",
|
||||
"description": "PreMiD adds cool Features to YouTube/YouTube Music. Like for example Discord Rich Presence integration, Media controls and much more.",
|
||||
"main": "index.js",
|
||||
"repository": "Timeraa/PreMiD",
|
||||
"scripts": {
|
||||
"start": "electron-forge start",
|
||||
"package": "electron-forge package",
|
||||
"make": "electron-forge make",
|
||||
"publish": "electron-forge publish",
|
||||
"lint": "echo \"No linting configured\"",
|
||||
"create-installer-mac": "electron-installer-dmg ./out/YT\\ Presence-darwin-x64/YT\\ Presence.app YT\\ Presence\\ Installer --overwrite --icon=./appIcon.icns --out=./dist",
|
||||
"create-installer-windows": "electron-installer-windows --src ./out/YT\\ Presence-win32-x64/ --dest ./dist"
|
||||
"start": "electron src/.",
|
||||
"pkgmac": "electron-packager ./src/ --out=./out/ --asar --overwrite --icon=./appIcon.ico --osx-sign.identity='Florian Metz'",
|
||||
"pkgwin": "electron-packager ./src/ --out=./out/ --overwrite --icon=./appIcon.ico",
|
||||
"installer-mac": "npm run pkgmac && node installer",
|
||||
"installer-win": "npm run pkgwin && node installer"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Timeraa",
|
||||
"license": "MIT",
|
||||
"config": {
|
||||
"forge": "./forge.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"auto-launch": "^5.0.5",
|
||||
"chalk": "^2.4.1",
|
||||
"discord-rpc": "^3.0.0",
|
||||
"electron-config": "^1.0.0",
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"express": "^4.16.3",
|
||||
"fs": "0.0.1-security",
|
||||
"html-entities": "^1.2.1",
|
||||
"menubar": "^5.2.3",
|
||||
"request": "^2.87.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "^6.0.0-beta.22",
|
||||
"@electron-forge/maker-deb": "^6.0.0-beta.22",
|
||||
"@electron-forge/maker-rpm": "^6.0.0-beta.22",
|
||||
"@electron-forge/maker-squirrel": "^6.0.0-beta.22",
|
||||
"@electron-forge/maker-zip": "^6.0.0-beta.22",
|
||||
"electron": "2.0.4",
|
||||
"chalk": "^2.4.1",
|
||||
"electron-installer-dmg": "^1.0.0",
|
||||
"electron-installer-windows": "^1.1.0"
|
||||
"electron-installer-windows": "^1.1.0",
|
||||
"electron-packager": "^12.2.0",
|
||||
"electron-winstaller": "^2.7.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#header {
|
||||
height: 50px;
|
||||
width: 100vw;
|
||||
background-color: #ce1d2a;
|
||||
box-shadow: 0px 0px 8px 2px #cccccc;
|
||||
}
|
||||
|
||||
#logo {
|
||||
position: relative;
|
||||
margin-top: 5px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#title {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
width: 100vw;
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#options {
|
||||
border-collapse: collapse;
|
||||
width: 90%;
|
||||
margin-left: 5%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
#options th:nth-child(1) {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
#options th:nth-child(2) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
#options tbody tr {
|
||||
transition: 1s ease-out;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
#options tbody tr:not(:last-child) {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#close-btn {
|
||||
transition: 0.1s all ease-out;
|
||||
margin-top: 10px;
|
||||
appearance: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
background-color: #ce1d2a;
|
||||
color: white;
|
||||
width: 75px;
|
||||
height: 30px;
|
||||
border-radius: 5px;
|
||||
font-size: 20px;
|
||||
margin-left: 50%;
|
||||
transform: translateX(-50%);
|
||||
box-shadow: 0px 0px 8px 2px #cccccc;
|
||||
}
|
||||
|
||||
#close-btn:hover {
|
||||
transform: translateX(-50%) scale(1.1);
|
||||
}
|
||||
|
||||
#close-btn:active {
|
||||
transform: translateX(-50%) scale(0.9);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
src: url("../fonts/Roboto/Roboto-Thin.ttf") format("truetype");
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
src: url("../fonts/Roboto/Roboto-Regular.ttf") format("truetype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
src: url("../fonts/Roboto/Roboto-Black.ttf") format("truetype");
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "Roboto", sans-serif;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
html {
|
||||
background-color: #ce1d2a;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#left {
|
||||
width: 50px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#logo {
|
||||
margin-top: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
#loaderWrapper h1 {
|
||||
position: absolute;
|
||||
width: 100vw;
|
||||
top: 30px;
|
||||
text-align: center;
|
||||
font-family: sans-serif;
|
||||
font-size: 15px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#loader {
|
||||
position: absolute;
|
||||
left: 100px;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
#loader #dot {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 100%;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#dot:nth-child(1) {
|
||||
animation-name: dotLoading;
|
||||
animation-duration: 1.5s;
|
||||
animation-timing-function: ease-in-out;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
#dot:nth-child(2) {
|
||||
animation-name: dotLoading;
|
||||
animation-duration: 1.5s;
|
||||
animation-delay: 0.25s;
|
||||
animation-timing-function: ease-in-out;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
#dot:nth-child(3) {
|
||||
animation-name: dotLoading;
|
||||
animation-duration: 1.5s;
|
||||
animation-delay: 0.5s;
|
||||
animation-timing-function: ease-in-out;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@keyframes dotLoading {
|
||||
0% {
|
||||
margin-left: 0px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
25% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
margin-left: 225px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
Before Width: | Height: | Size: 379 B After Width: | Height: | Size: 885 B |
|
Before Width: | Height: | Size: 660 B After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/images/logo.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
@@ -1,159 +0,0 @@
|
||||
//* Declare needed constants
|
||||
const remote = require('electron').remote
|
||||
const app = remote.app
|
||||
const AutoLaunch = require('auto-launch');
|
||||
const Config = require('electron-config')
|
||||
const userSettings = new Config({
|
||||
name: "userSettings"
|
||||
})
|
||||
|
||||
|
||||
var togglePresence,
|
||||
toggleYouTube,
|
||||
toggleYouTubeMusic,
|
||||
toggleTitleMenubar;
|
||||
|
||||
$(() => {
|
||||
var os = require('os')
|
||||
if (os.platform() == "darwin") {
|
||||
$('<tr><td class="noselect">Title menubar</td><td class="right"><label class="switch"><input class="toggleTitleMenubar" type="checkbox"><span class="slider round"></span></label></td></tr>').insertAfter('.ytmToggle')
|
||||
}
|
||||
|
||||
togglePresence = $(".togglePresence"),
|
||||
toggleYouTube = $(".toggleYouTube"),
|
||||
toggleYouTubeMusic = $(".toggleYouTubeMusic");
|
||||
toggleTitleMenubar = $(".toggleTitleMenubar");
|
||||
toggleAutoLaunch = $(".toggleAutoLaunch");
|
||||
toggleAutoUpdate = $(".toggleAutoUpdate");
|
||||
|
||||
togglePresence.change(switchPresence);
|
||||
toggleYouTube.change(switchYouTube);
|
||||
toggleYouTubeMusic.change(switchYouTubeMusic);
|
||||
toggleTitleMenubar.change(switchTitleMenubar);
|
||||
toggleAutoLaunch.change(switchAutomaticStartup);
|
||||
toggleAutoUpdate.change(switchAutoUpdate);
|
||||
|
||||
if (userSettings.get('enabled') == true) togglePresence.prop("checked", true)
|
||||
else {
|
||||
togglePresence.prop("checked", false)
|
||||
toggleYouTube.prop("checked", false)
|
||||
toggleYouTubeMusic.prop("checked", false)
|
||||
toggleYouTube.attr("disabled", "disabled")
|
||||
toggleYouTubeMusic.attr("disabled", "disabled")
|
||||
toggleTitleMenubar.attr("disabled", "disabled")
|
||||
}
|
||||
|
||||
if (userSettings.get('youTube') == true) {
|
||||
toggleYouTube.prop("checked", true)
|
||||
toggleYouTube.removeAttr("disabled")
|
||||
} else toggleYouTube.prop("checked", false)
|
||||
|
||||
if (userSettings.get('youTubeMusic') == true) {
|
||||
toggleYouTubeMusic.prop("checked", true)
|
||||
toggleYouTubeMusic.removeAttr("disabled")
|
||||
} else toggleYouTubeMusic.prop("checked", false)
|
||||
|
||||
if (userSettings.get('titleMenubar') == true) {
|
||||
toggleTitleMenubar.prop("checked", true)
|
||||
toggleTitleMenubar.removeAttr("disabled")
|
||||
} else toggleTitleMenubar.prop("checked", false)
|
||||
|
||||
if (userSettings.get('autoLaunch') == true) {
|
||||
toggleAutoLaunch.prop("checked", true)
|
||||
toggleAutoLaunch.removeAttr("disabled")
|
||||
} else toggleAutoLaunch.prop("checked", false)
|
||||
|
||||
if (userSettings.get('autoUpdateCheck') == true) {
|
||||
toggleAutoUpdate.prop("checked", true)
|
||||
toggleAutoUpdate.removeAttr("disabled")
|
||||
} else toggleAutoUpdate.prop("checked", false)
|
||||
})
|
||||
|
||||
function switchPresence() {
|
||||
if (userSettings.get('enabled') == true) {
|
||||
userSettings.set('enabled', false);
|
||||
userSettings.set('youTube', false);
|
||||
userSettings.set('youTubeMusic', false);
|
||||
userSettings.set('titleMenubar', false);
|
||||
toggleYouTube.prop("checked", false)
|
||||
toggleYouTube.attr("disabled", "disabled")
|
||||
toggleYouTubeMusic.prop("checked", false)
|
||||
toggleYouTubeMusic.attr("disabled", "disabled")
|
||||
toggleTitleMenubar.prop("checked", false)
|
||||
toggleTitleMenubar.attr("disabled", "disabled")
|
||||
} else {
|
||||
userSettings.set('enabled', true);
|
||||
toggleYouTube.removeAttr("disabled")
|
||||
toggleYouTubeMusic.removeAttr("disabled")
|
||||
toggleTitleMenubar.removeAttr("disabled")
|
||||
}
|
||||
}
|
||||
|
||||
function switchYouTube() {
|
||||
if (userSettings.get('youTube') == true) {
|
||||
userSettings.set('youTube', false)
|
||||
toggleYouTube.prop("checked", false)
|
||||
} else {
|
||||
userSettings.set('youTube', true)
|
||||
toggleYouTube.prop("checked", true)
|
||||
}
|
||||
}
|
||||
|
||||
function switchYouTubeMusic() {
|
||||
if (userSettings.get('youTubeMusic') == true) {
|
||||
userSettings.set('youTubeMusic', false);
|
||||
toggleYouTubeMusic.prop("checked", false)
|
||||
} else {
|
||||
userSettings.set('youTubeMusic', true);
|
||||
toggleYouTubeMusic.prop("checked", true)
|
||||
}
|
||||
}
|
||||
|
||||
function switchTitleMenubar() {
|
||||
if (userSettings.get('titleMenubar') == true) {
|
||||
userSettings.set('titleMenubar', false);
|
||||
toggleTitleMenubar.prop("checked", false)
|
||||
} else {
|
||||
userSettings.set('titleMenubar', true);
|
||||
toggleTitleMenubar.prop("checked", true)
|
||||
}
|
||||
}
|
||||
|
||||
function switchAutomaticStartup() {
|
||||
//* Add App to AutoLaunch
|
||||
let autoLaunch = new AutoLaunch({
|
||||
name: 'YT Presence',
|
||||
path: app.getPath('exe'),
|
||||
isHidden: true
|
||||
});
|
||||
|
||||
if (userSettings.get('autoLaunch') == true) {
|
||||
autoLaunch.isEnabled().then((isEnabled) => {
|
||||
if(isEnabled) autoLaunch.disable()
|
||||
}).catch((err) => {
|
||||
console.log("Error while adding App to autostart.")
|
||||
})
|
||||
|
||||
userSettings.set('autoLaunch', false);
|
||||
toggleAutoLaunch.prop("checked", false)
|
||||
} else {
|
||||
autoLaunch.isEnabled().then((isEnabled) => {
|
||||
if(!isEnabled) autoLaunch.enable()
|
||||
}).catch((err) => {
|
||||
console.log("Error while adding App to autostart.")
|
||||
})
|
||||
|
||||
userSettings.set('autoLaunch', true);
|
||||
toggleAutoLaunch.prop("checked", true)
|
||||
}
|
||||
}
|
||||
|
||||
function switchAutoUpdate() {
|
||||
if (userSettings.get('autoUpdateCheck') == true) {
|
||||
userSettings.set('autoUpdateCheck', false);
|
||||
toggleAutoUpdate.prop("checked", false)
|
||||
} else {
|
||||
userSettings.set('autoUpdateCheck', true);
|
||||
toggleAutoUpdate.prop("checked", true)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"yt_client_id": "463097721130188830",
|
||||
"ytm_client_id": "463151177836658699",
|
||||
"version": 1.0
|
||||
}
|
||||
106
src/index.js
@@ -1,44 +1,49 @@
|
||||
//* Handle Winstall
|
||||
require('./util/handleWinstall')
|
||||
require('./util/handleWinstall')
|
||||
|
||||
//#region Define constants
|
||||
//* Declare needed constants
|
||||
const {app} = require('electron')
|
||||
|
||||
const AutoLaunch = require('auto-launch')
|
||||
//* Require config
|
||||
const config = require('./config.json');
|
||||
const constants = require('./util/constants')
|
||||
var pjson = require('./package.json');
|
||||
//* Require electron-config
|
||||
var os = require('os')
|
||||
//* Update constant in file
|
||||
constants.platform = os.platform()
|
||||
const os = require('os')
|
||||
//* Require Update checker
|
||||
const updater = require('./util/updateChecker')
|
||||
//* Require Needed packages
|
||||
const chalk = require("chalk")
|
||||
//* Setup electron-config
|
||||
const Config = require('electron-config');
|
||||
const userSettings = new Config({
|
||||
name: "userSettings"
|
||||
});
|
||||
//#endregion
|
||||
|
||||
app.setAppUserModelId("eu.Timeraa.yt-presence")
|
||||
//* Set app user model id
|
||||
app.setAppUserModelId("eu.Timeraa.premid")
|
||||
|
||||
//* Define Global Variables
|
||||
global.PLATFORM = os.platform()
|
||||
global.UPDATEAVAIABLE = ""
|
||||
global.VERSION = config.version
|
||||
global.VERSIONSTRING = VERSION + "-DEVBUILD"
|
||||
global.VERSION = pjson.productVersion
|
||||
|
||||
if(pjson.devBuild)
|
||||
global.VERSIONSTRING = VERSION + "-DEV";
|
||||
else
|
||||
global.VERSIONSTRING = VERSION;
|
||||
|
||||
global.BROWSERCONNECTIONSTATE = "NOT_CONNECTED"
|
||||
global.EXTENSIONSOCKET = null
|
||||
global.TRAY = null
|
||||
global.CONSOLEPREFIX = chalk.bold(chalk.hex('#596cae')("PreMiD")) + chalk.hex('#ffffff')(": ")
|
||||
|
||||
//* YTM global vars
|
||||
global.CURRENTSONGTITLE = ""
|
||||
global.CURRENTSONGAUTHORS = []
|
||||
global.CURRENTSONGAUTHORSSTRING = ""
|
||||
global.CURRENTSONGSTARTTIME = ""
|
||||
global.CURRENTSONGSTARTTIMESECONDS = ""
|
||||
global.CURRENTSONGENDTIME = ""
|
||||
global.CONSOLEPREFIX = chalk.bold(chalk.bgHex('#db0918')(chalk.hex('#000000')(" Y") + chalk.hex('#ffffff')("T "))) + chalk.cyan(" Presence") + chalk.hex('#ffffff')(": ")
|
||||
|
||||
//* Clear console
|
||||
process.stdout.write("\u001b[2J\u001b[0;0H");
|
||||
|
||||
//* Single Instance Check
|
||||
var iShouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) {
|
||||
return true;
|
||||
});
|
||||
var iShouldQuit = app.makeSingleInstance(() => {return true});
|
||||
|
||||
if(iShouldQuit){
|
||||
console.log(CONSOLEPREFIX + chalk.red("App already running, closing current instance..."))
|
||||
@@ -46,62 +51,37 @@ if(iShouldQuit){
|
||||
return;
|
||||
}
|
||||
|
||||
//* Setup electron-config
|
||||
const Config = require('electron-config');
|
||||
|
||||
const userSettings = new Config({
|
||||
name: "userSettings"
|
||||
});
|
||||
|
||||
//* Set default values for electon-config userSettings
|
||||
if(userSettings.get('enabled') == undefined) userSettings.set('enabled', true)
|
||||
if(userSettings.get('youTube') == undefined) userSettings.set('youTube', true)
|
||||
if(userSettings.get('youTubeMusic') == undefined) userSettings.set('youTubeMusic', true)
|
||||
if(userSettings.get('titleMenubar') == undefined) userSettings.set('titleMenubar', true)
|
||||
if(userSettings.get('autoStart') == undefined) userSettings.set('autoStart', true)
|
||||
if(userSettings.get('autoUpdateCheck') == undefined) userSettings.set('autoUpdateCheck', true)
|
||||
if(userSettings.get('mediaControls') == undefined) userSettings.set('mediaControls', true)
|
||||
|
||||
|
||||
//* Set dock Badge to version
|
||||
if(constants.platform == "darwin") {
|
||||
if(PLATFORM == "darwin") {
|
||||
app.dock.setBadge("V" + VERSION)
|
||||
}
|
||||
|
||||
console.log(CONSOLEPREFIX + chalk.yellow("Loading..."))
|
||||
|
||||
//* Setup MenuBar
|
||||
require('./menubar/setup')
|
||||
|
||||
//* App ready
|
||||
const appReady = () => {
|
||||
|
||||
if(userSettings.get('autoLaunch') == undefined) {
|
||||
userSettings.set('autoLaunch', true)
|
||||
//* Add App to AutoLaunch
|
||||
console.log(CONSOLEPREFIX + chalk.yellow("Adding App to autostart..."))
|
||||
let autoLaunch = new AutoLaunch({
|
||||
name: 'YT Presence',
|
||||
path: app.getPath('exe'),
|
||||
isHidden: true
|
||||
});
|
||||
|
||||
//* Enable AutoLaunch if disabled
|
||||
autoLaunch.isEnabled().then((isEnabled) => {
|
||||
if (!isEnabled) autoLaunch.enable();
|
||||
console.log(CONSOLEPREFIX + chalk.green("Added App to autostart."))
|
||||
})
|
||||
//* Catch error
|
||||
.catch(function(err) {
|
||||
console.log(CONSOLEPREFIX + chalk.red("Error while adding App to autostart."))
|
||||
})
|
||||
}
|
||||
|
||||
if(userSettings.get('autoUpdateCheck') == true) {
|
||||
//* Check for update
|
||||
updater.checkForUpdate(true)
|
||||
}
|
||||
|
||||
const appReady = async () => {
|
||||
//* Setup MenuBar
|
||||
require('./tray/createTray').run()
|
||||
//* Require shortcuts
|
||||
require('./util/shortcutHandler').register()
|
||||
//* Include PresenceHandler
|
||||
require('./presenceHandler.js')
|
||||
//* Auto launch
|
||||
require('./util/autoLaunch')
|
||||
|
||||
//* Automatically check for update
|
||||
if(userSettings.get('autoUpdateCheck') == true)
|
||||
updater.checkForUpdate(true)
|
||||
|
||||
//* hide Dock icon when everything running
|
||||
if(PLATFORM == "darwin") app.dock.hide()
|
||||
}
|
||||
|
||||
//* Register Handler
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
const MenuBar = require('menubar')
|
||||
const path = require('path')
|
||||
const constants = require("../util/constants")
|
||||
const os = require('os');
|
||||
const updater = require('../util/updateChecker')
|
||||
|
||||
const {Menu, MenuItem, BrowserWindow} = require('electron')
|
||||
|
||||
var menuBarHeight;
|
||||
|
||||
//* Create MenuBar
|
||||
constants.menuBar = MenuBar({
|
||||
icon: path.join(__dirname, "../assets/images/icon.png"),
|
||||
showOnAllWorkspaces: true,
|
||||
enableLargerThanScreen: false,
|
||||
resizable: false,
|
||||
height: menuBarHeight,
|
||||
width: 250,
|
||||
backgroundColor: 'black',
|
||||
})
|
||||
|
||||
constants.menuBar.on('ready', () => {
|
||||
//* Create Menu for menuBar
|
||||
setupMenu(constants.menuBar)
|
||||
})
|
||||
|
||||
//* Create Menu for menuBar
|
||||
function setupMenu(menuBar) {
|
||||
constants.menuBarMenu = new Menu()
|
||||
constants.menuBarMenu.append(new MenuItem({
|
||||
label: `YT Presence | V${VERSIONSTRING}`,
|
||||
enabled: false,
|
||||
icon: path.join(__dirname, "../assets/images/icon.png")
|
||||
}))
|
||||
constants.menuBarMenu.append(new MenuItem({
|
||||
click: checkForUpdate,
|
||||
label: "Check for update"
|
||||
}))
|
||||
constants.menuBarMenu.append(new MenuItem({
|
||||
type: "separator"
|
||||
}))
|
||||
constants.menuBarMenu.append(new MenuItem({
|
||||
click: showSettingsPanel,
|
||||
label: "Preferences"
|
||||
}))
|
||||
constants.menuBarMenu.append(new MenuItem({
|
||||
type: "separator"
|
||||
}))
|
||||
constants.menuBarMenu.append(new MenuItem({
|
||||
role: "quit",
|
||||
}))
|
||||
|
||||
constants.menuBar.tray.setContextMenu(constants.menuBarMenu)
|
||||
}
|
||||
|
||||
function checkForUpdate() {
|
||||
updater.checkForUpdate(true, true)
|
||||
}
|
||||
|
||||
function showSettingsPanel() {
|
||||
|
||||
switch(os.platform()) {
|
||||
case "darwin":
|
||||
menuBarHeight = 375;
|
||||
break;
|
||||
default:
|
||||
menuBarHeight = 335;
|
||||
break;
|
||||
}
|
||||
|
||||
var settingsWindow = new BrowserWindow({
|
||||
center: true,
|
||||
maximizable: false,
|
||||
resizable: false,
|
||||
show: false,
|
||||
height: menuBarHeight,
|
||||
width: 400
|
||||
})
|
||||
|
||||
settingsWindow.loadURL("file://" + path.join(__dirname, "../preferences.html"))
|
||||
|
||||
settingsWindow.on('ready-to-show', () => {
|
||||
settingsWindow.show()
|
||||
})
|
||||
|
||||
settingsWindow.on('blur', () => {
|
||||
settingsWindow.close()
|
||||
})
|
||||
|
||||
settingsWindow.on('close', () => {
|
||||
settingsWindow = null;
|
||||
})
|
||||
}
|
||||
5897
src/package-lock.json
generated
Normal file
25
src/package.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "premid",
|
||||
"productName": "PreMiD",
|
||||
"productVersion": "1.2",
|
||||
"version": "1.2.0",
|
||||
"description": "PreMiD adds cool Features to YouTube/YouTube Music. Like for example Discord Rich Presence integration, Media controls and much more.",
|
||||
"main": "index.js",
|
||||
"repository": "Timeraa/PreMiD",
|
||||
"keywords": [],
|
||||
"author": "Timeraa",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"auto-launch": "^5.0.5",
|
||||
"chalk": "^2.4.1",
|
||||
"discord-rpc": "^3.0.1",
|
||||
"electron-config": "^1.0.0",
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"express": "^4.16.4",
|
||||
"request": "^2.88.0",
|
||||
"socket.io": "^2.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron-prebuilt-compile": "3.0.2"
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Preferences | YT Presence</title>
|
||||
<link rel="icon" type="image/png" href="assets/images/icon@2x.png">
|
||||
<link href="assets/css/reset.css" rel="stylesheet">
|
||||
<link href="assets/css/preferences.css" rel="stylesheet">
|
||||
<link href="assets/css/inputs.css" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700,800" rel="stylesheet">
|
||||
|
||||
<script>if (typeof module === 'object') { window.module = module; module = undefined; }</script>
|
||||
|
||||
<script src="assets/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="assets/js/preferences.js"></script>
|
||||
|
||||
<script>if (window.module) module = window.module;</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="header">
|
||||
<img id="logo" src="assets/images/icon@2x.png" draggable="false">
|
||||
<h1 id="title">Preferences</h1>
|
||||
</div>
|
||||
<div id="content">
|
||||
<table id="options">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Enabled</td>
|
||||
<td>
|
||||
<label class="switch">
|
||||
<input class="togglePresence" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>YouTube</td>
|
||||
<td>
|
||||
<label class="switch">
|
||||
<input class="toggleYouTube" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="ytmToggle">
|
||||
<td>YouTube Music</td>
|
||||
<td>
|
||||
<label class="switch">
|
||||
<input class="toggleYouTubeMusic" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Launch on system startup</td>
|
||||
<td>
|
||||
<label class="switch">
|
||||
<input class="toggleAutoLaunch" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Automatically check for updates</td>
|
||||
<td>
|
||||
<label class="switch">
|
||||
<input class="toggleAutoUpdate" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Dark mode</td>
|
||||
<td>
|
||||
<label class="switch">
|
||||
<input class="toggleDarkMode" type="checkbox">
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<input id="close-btn" type="button" value="Close">
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
document.getElementById("close-btn").addEventListener("click", function (e) {
|
||||
var window = remote.getCurrentWindow();
|
||||
window.close();
|
||||
});
|
||||
</script>
|
||||
|
||||
</html>
|
||||
@@ -1,94 +1,92 @@
|
||||
//* Require needed packages
|
||||
const chalk = require("chalk")
|
||||
const express = require("express")
|
||||
var constants = require('./util/constants.js')
|
||||
let YTM = require('./presences/handleYTM.js');
|
||||
let YT = require('./presences/handleYT.js');
|
||||
const DiscordRPC = require('discord-rpc')
|
||||
|
||||
//* Require needed packages
|
||||
const chalk = require("chalk"),
|
||||
express = require("express")
|
||||
|
||||
//* Create server to listen for extension
|
||||
var extension = express(),
|
||||
http = require('http'),
|
||||
socketServer = http.createServer(extension),
|
||||
io = require('socket.io')(socketServer);
|
||||
|
||||
//* Load Config
|
||||
const Config = require('electron-config');
|
||||
const userSettings = new Config({
|
||||
name: "userSettings"
|
||||
});
|
||||
|
||||
//* Create APP
|
||||
const app = express()
|
||||
|
||||
app.use(express.json());
|
||||
|
||||
let data
|
||||
|
||||
var keepAliveSwitch = 0
|
||||
//* Define needed variables
|
||||
var lastKeepAliveSwitch = 0
|
||||
|
||||
//* Keep alive check to automatically remove presence if browser not running/not using YT
|
||||
setInterval(keepAliveCheck, 1000)
|
||||
|
||||
function keepAliveCheck() {
|
||||
if(lastKeepAliveSwitch > keepAliveSwitch + 10) {
|
||||
constants.menuBar.tray.setTitle("")
|
||||
constants.ytmrpc.clearActivity()
|
||||
async function keepAliveCheck() {
|
||||
if (lastKeepAliveSwitch > 0) {
|
||||
setupServices.forEach(service => {
|
||||
service.rpc.destroy()
|
||||
})
|
||||
setupServices = []
|
||||
serviceLogins = []
|
||||
if(PLATFORM == "darwin") TRAY.setTitle("");
|
||||
}
|
||||
lastKeepAliveSwitch += 1
|
||||
}
|
||||
|
||||
app.post("/", async (request, response) => {
|
||||
constants.lastResponse = new Date().getTime();
|
||||
data = request.body
|
||||
if(data.connected === true) {
|
||||
//* Check if presence is ready
|
||||
if(constants.chromeConnected == false) {
|
||||
constants.chromeConnected = true;
|
||||
constants.menuBar.tray.setTitle("Chrome found!")
|
||||
console.log(CONSOLEPREFIX + chalk.green("Chrome client connected."))
|
||||
setTimeout(function() {
|
||||
if(data.currentSongAuthor == undefined) {
|
||||
constants.menuBar.tray.setTitle("")
|
||||
}
|
||||
constants.introRan = true
|
||||
}, 5*1000)
|
||||
}
|
||||
if(data.service != "keepAlive" && data.service == "ytm") {
|
||||
lastKeepAliveSwitch = 0
|
||||
keepAliveSwitch = 0
|
||||
if(userSettings.get('youTubeMusic') == true) {
|
||||
if(constants.introRan && constants.chromeConnected && constants.presenceReady) {
|
||||
if(serviceType(data.service) == "ytm") YTM.updatePresence(data)
|
||||
}
|
||||
} else {
|
||||
constants.menuBar.tray.setTitle("")
|
||||
constants.ytmrpc.clearActivity()
|
||||
}
|
||||
} else if(data.service != "keepAlive" && data.service == "yt") {
|
||||
lastKeepAliveSwitch = 0
|
||||
keepAliveSwitch = 0
|
||||
if(userSettings.get('youTube') == true) {
|
||||
if(constants.introRan && constants.chromeConnected && constants.presenceReady) {
|
||||
if(serviceType(data.service) == "yt") YT.updatePresence(data)
|
||||
}
|
||||
} else {
|
||||
constants.menuBar.tray.setTitle("")
|
||||
constants.ytrpc.clearActivity()
|
||||
}
|
||||
} else {
|
||||
if(keepAliveSwitch >= 3) {
|
||||
constants.menuBar.tray.setTitle("")
|
||||
constants.ytmrpc.clearActivity()
|
||||
}
|
||||
keepAliveSwitch += 1
|
||||
}
|
||||
}
|
||||
return response.sendStatus(200);
|
||||
//* Listen on port 3020
|
||||
socketServer.listen(3020, () => {
|
||||
console.log(CONSOLEPREFIX + chalk.green("Listening on Port 3020"))
|
||||
});
|
||||
|
||||
//* Socket connection event
|
||||
io.on('connection', function (socket) {
|
||||
global.EXTENSIONSOCKET = socket
|
||||
BROWSERCONNECTIONSTATE = "CONNECTED"
|
||||
|
||||
socket.on('playBackChange', updatePresence)
|
||||
socket.on('updateData', updatePresence)
|
||||
socket.on('settingsChange', require('./util/settingsHandler'))
|
||||
})
|
||||
|
||||
function serviceType(service) {
|
||||
switch(service) {
|
||||
case "ytm":
|
||||
return "ytm"
|
||||
case "yt":
|
||||
return "yt"
|
||||
default:
|
||||
return false
|
||||
var setupServices = [],
|
||||
serviceLogins = [],
|
||||
presencePauseSwitch = 0
|
||||
|
||||
//* Updates the presence with the incomming data
|
||||
async function updatePresence(data) {
|
||||
lastKeepAliveSwitch = 0;
|
||||
|
||||
var setupService = setupServices.find(svice => svice.serviceName == data.service);
|
||||
|
||||
if(!data.playback) presencePauseSwitch++; else presencePauseSwitch = 0;
|
||||
if(presencePauseSwitch >= 60) {
|
||||
if(setupService != null) {
|
||||
setupService.rpc.clearActivity()
|
||||
if(PLATFORM == "darwin") TRAY.setTitle("");
|
||||
}
|
||||
} else {
|
||||
if(setupService) {
|
||||
if(userSettings.get('titleMenubar')) if(PLATFORM == "darwin" && data.playback) TRAY.setTitle(data.trayTitle); else TRAY.setTitle("");
|
||||
setupService.rpc.setActivity(data.presenceData)
|
||||
} else {
|
||||
tryLogin(data.service, data.clientID)
|
||||
serviceLogins.push({serviceName: data.service, intervalID: setInterval(() => tryLogin(data.service, data.clientID), 10 * 1000)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//* Listen on port 3000
|
||||
app.listen(3000, () => console.log(CONSOLEPREFIX + chalk.green("Listening on Port 3000")));
|
||||
|
||||
/**
|
||||
* Try to login to RPC until connected
|
||||
*/
|
||||
async function tryLogin(service, clientID) {
|
||||
setupServices.push({rpc: new DiscordRPC.Client({ transport: "ipc" }), serviceName: service, ready: false})
|
||||
var serviceRPC = setupServices.find(svice => svice.serviceName == service)
|
||||
serviceRPC.rpc.login({ clientId: clientID })
|
||||
.catch(err => console.log(`${CONSOLEPREFIX}PreMiD - RPC: ${err.message}`))
|
||||
serviceRPC.rpc.on("ready", () => {
|
||||
clearInterval(serviceLogins.find(svice => svice.serviceName == service).intervalID)
|
||||
serviceRPC.ready = true
|
||||
})
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
const constants = require("../util/constants.js");
|
||||
const { yt_client_id } = require("../config.json");
|
||||
const Entities = require("html-entities").AllHtmlEntities;
|
||||
const entities = new Entities();
|
||||
|
||||
const Config = require("electron-config");
|
||||
const userSettings = new Config({
|
||||
name: 'userSettings'
|
||||
})
|
||||
|
||||
let startTime = new Date(),
|
||||
lastTitle
|
||||
|
||||
async function updatePresence(data) {
|
||||
if(lastTitle != data.currentSongTitle) {
|
||||
startTime = new Date()
|
||||
}
|
||||
if(data.url.includes("/watch?v")) {
|
||||
lastTitle = data.currentSongTitle;
|
||||
if (
|
||||
(data.currentSongAuthor && data.currentSongTitle) != undefined &&
|
||||
data.currentSongAuthor != "" &&
|
||||
data.currentSongTitle != ""
|
||||
) {
|
||||
if(userSettings.get('titleMenubar')) {
|
||||
constants.menuBar.tray.setTitle(entities.decode(data.currentSongTitle));
|
||||
} else constants.menuBar.tray.setTitle("")
|
||||
constants.ytrpc.setActivity({
|
||||
details: entities.decode(data.currentSongTitle),
|
||||
state: entities.decode(data.currentSongAuthor),
|
||||
smallImageKey: "play",
|
||||
smallImageText: "Playing back.",
|
||||
startTimestamp: startTime,
|
||||
largeImageKey: "yt_lg",
|
||||
instance: true
|
||||
});
|
||||
}
|
||||
} else {
|
||||
constants.menuBar.tray.setTitle(entities.decode(data.currentSongTitle));
|
||||
constants.ytrpc.setActivity({
|
||||
details: "Searching",
|
||||
state: "for a video...",
|
||||
largeImageKey: "yt_lg",
|
||||
instance: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
constants.ytrpc.on("ready", () => {
|
||||
constants.presenceReady = true;
|
||||
});
|
||||
|
||||
exports.updatePresence = updatePresence;
|
||||
|
||||
constants.ytrpc.login({clientId: yt_client_id}).catch(console.error);
|
||||
@@ -1,175 +0,0 @@
|
||||
const constants = require("../util/constants.js");
|
||||
const { ytm_client_id } = require("../config.json");
|
||||
const Config = require("electron-config");
|
||||
const chalk = require("chalk");
|
||||
|
||||
const userSettings = new Config({
|
||||
name: 'userSettings'
|
||||
})
|
||||
|
||||
const Entities = require("html-entities").AllHtmlEntities;
|
||||
const entities = new Entities();
|
||||
|
||||
let startTime = new Date(),
|
||||
endTime = new Date(),
|
||||
lastStartingTime;
|
||||
|
||||
|
||||
let lastSongTitle = null,
|
||||
lastSongAuthors = [],
|
||||
lastSongStartTime,
|
||||
playbackWasPaused,
|
||||
playbackPausedDebug = 0,
|
||||
nextSongPauseDebug = 0,
|
||||
rpcRemoveCountdown = 0,
|
||||
ytPresenceVersionString = `YT Presence V${VERSIONSTRING}`;
|
||||
|
||||
async function updatePresence(data) {
|
||||
var CURRENTSONGTITLE = data.currentSongTitle,
|
||||
CURRENTSONGAUTHORS = data.currentSongAuthors,
|
||||
CURRENTSONGSTARTTIME = data.currentSongStartTime,
|
||||
CURRENTSONGSTARTTIMESECONDS = data.currentSongStartTimeSeconds,
|
||||
CURRENTSONGENDTIME = data.currentSongEndTime
|
||||
|
||||
//* Create author string from author array
|
||||
CURRENTSONGAUTHORS.forEach((author, index, authors) => {
|
||||
if(index == 0) {
|
||||
CURRENTSONGAUTHORSSTRING = author
|
||||
} else if(index < authors.length - 2) {
|
||||
CURRENTSONGAUTHORSSTRING = CURRENTSONGAUTHORSSTRING + ", " + author
|
||||
} else if(index < authors.length - 1) {
|
||||
CURRENTSONGAUTHORSSTRING = CURRENTSONGAUTHORSSTRING + " and " + author
|
||||
} else {
|
||||
CURRENTSONGAUTHORSSTRING = CURRENTSONGAUTHORSSTRING + " - " + author
|
||||
}
|
||||
});
|
||||
|
||||
//* Update songTitle if changed
|
||||
if(lastSongTitle != CURRENTSONGTITLE) {
|
||||
//* Only update if authors changed aswell (Debug for Presence)
|
||||
if(lastSongAuthors.join() != CURRENTSONGAUTHORS.join()) {
|
||||
if(CURRENTSONGTITLE != "" && CURRENTSONGAUTHORS.join() != "") {
|
||||
|
||||
CURRENTSONGSTARTTIME = Math.floor(CURRENTSONGSTARTTIME / 1000)
|
||||
if(CURRENTSONGSTARTTIME != CURRENTSONGENDTIME) {
|
||||
lastSongTitle = CURRENTSONGTITLE
|
||||
lastSongAuthors = CURRENTSONGAUTHORS
|
||||
lastSongStartTime = CURRENTSONGSTARTTIMESECONDS
|
||||
|
||||
rpcRemoveCountdown = 0
|
||||
|
||||
nextSongPauseDebug = 2
|
||||
|
||||
if(playbackWasPaused) playbackWasPaused = false
|
||||
|
||||
console.log(CONSOLEPREFIX + chalk.yellow('Song changed, now playing: ') + chalk.green(entities.decode(CURRENTSONGTITLE)) + chalk.yellow('.'))
|
||||
|
||||
//* Set menuBar title if enabled
|
||||
if(userSettings.get('titleMenubar')) constants.menuBar.tray.setTitle(entities.decode(CURRENTSONGTITLE))
|
||||
|
||||
//* Update ytm presence
|
||||
updateYTMPresence({
|
||||
details: entities.decode(CURRENTSONGTITLE),
|
||||
state: entities.decode(CURRENTSONGAUTHORSSTRING),
|
||||
largeImageKey: "ytm_lg",
|
||||
largeImageText: ytPresenceVersionString,
|
||||
smallImageKey: "play",
|
||||
smallImageText: "Playing back.",
|
||||
startTimestamp: CURRENTSONGSTARTTIME,
|
||||
endTimestamp: CURRENTSONGENDTIME,
|
||||
instance: true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(nextSongPauseDebug == 0) {
|
||||
if(lastSongStartTime == CURRENTSONGSTARTTIMESECONDS) {
|
||||
if(!playbackWasPaused) {
|
||||
if(playbackPausedDebug == 1) {
|
||||
playbackPausedDebug = 0;
|
||||
playbackWasPaused = true
|
||||
lastSongStartTime = CURRENTSONGSTARTTIMESECONDS
|
||||
|
||||
console.log(CONSOLEPREFIX + chalk.yellow('Song paused.'))
|
||||
|
||||
//* Update ytm presence
|
||||
updateYTMPresence({
|
||||
details: entities.decode(CURRENTSONGTITLE),
|
||||
state: entities.decode(CURRENTSONGAUTHORSSTRING),
|
||||
largeImageKey: "ytm_lg",
|
||||
largeImageText: ytPresenceVersionString,
|
||||
smallImageKey: "pause",
|
||||
smallImageText: "Playing paused.",
|
||||
instance: true
|
||||
})
|
||||
} else {
|
||||
playbackPausedDebug++
|
||||
}
|
||||
}
|
||||
if(rpcRemoveCountdown == 60) {
|
||||
constants.ytmrpc.clearActivity()
|
||||
//* Set menuBar title if enabled
|
||||
if(userSettings.get('titleMenubar')) constants.menuBar.tray.setTitle("")
|
||||
} else {
|
||||
rpcRemoveCountdown++
|
||||
}
|
||||
} else if(playbackWasPaused) {
|
||||
|
||||
console.log(CONSOLEPREFIX + chalk.yellow('Song resumed.'))
|
||||
//* Set menuBar title if enabled
|
||||
if(userSettings.get('titleMenubar')) constants.menuBar.tray.setTitle(entities.decode(CURRENTSONGTITLE))
|
||||
|
||||
rpcRemoveCountdown = 0
|
||||
|
||||
//* Update ytm presence
|
||||
updateYTMPresence({
|
||||
details: entities.decode(CURRENTSONGTITLE),
|
||||
state: entities.decode(CURRENTSONGAUTHORSSTRING),
|
||||
largeImageKey: "ytm_lg",
|
||||
largeImageText: ytPresenceVersionString,
|
||||
smallImageKey: "play",
|
||||
smallImageText: "Playing back.",
|
||||
startTimestamp: Math.floor(CURRENTSONGSTARTTIME / 1000),
|
||||
endTimestamp: CURRENTSONGENDTIME,
|
||||
instance: true
|
||||
})
|
||||
|
||||
playbackWasPaused = false
|
||||
} else {
|
||||
var difference = Math.abs(lastSongStartTime - CURRENTSONGSTARTTIMESECONDS +1);
|
||||
if(difference != 0) {
|
||||
console.log(CONSOLEPREFIX + chalk.yellow(`Song time changed. Difference: ${difference} seconds.`))
|
||||
//* Update ytm presence
|
||||
updateYTMPresence({
|
||||
details: entities.decode(CURRENTSONGTITLE),
|
||||
state: entities.decode(CURRENTSONGAUTHORSSTRING),
|
||||
smallImageKey: "play",
|
||||
smallImageText: "Playing back.",
|
||||
largeImageKey: "ytm_lg",
|
||||
startTimestamp: Math.floor(CURRENTSONGSTARTTIME / 1000),
|
||||
endTimestamp: CURRENTSONGENDTIME,
|
||||
instance: true
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nextSongPauseDebug--
|
||||
}
|
||||
lastSongStartTime = CURRENTSONGSTARTTIMESECONDS
|
||||
}
|
||||
}
|
||||
|
||||
function updateYTMPresence(data) {
|
||||
constants.ytmrpc.setActivity(data);
|
||||
}
|
||||
|
||||
constants.ytmrpc.on("ready", () => {
|
||||
constants.presenceReady = true;
|
||||
});
|
||||
|
||||
exports.updatePresence = updatePresence;
|
||||
|
||||
constants.ytmrpc.login({clientId: ytm_client_id}).catch(console.error);
|
||||
|
||||
//* Catch Discord RPC errors
|
||||
22
src/tray/createTray.js
Normal file
@@ -0,0 +1,22 @@
|
||||
const path = require('path')
|
||||
const {Tray, Menu, MenuItem} = require('electron')
|
||||
|
||||
exports.run = () => {
|
||||
TRAY = new Tray(path.join(__dirname, "../assets/images/icon.png"))
|
||||
TRAY.setToolTip(`PreMiD V${VERSIONSTRING}`)
|
||||
var menuBarMenu = new Menu()
|
||||
menuBarMenu.append(new MenuItem({
|
||||
label: `PreMiD | V${VERSIONSTRING}`,
|
||||
enabled: false,
|
||||
icon: path.join(__dirname, "../assets/images/icon.png")
|
||||
}))
|
||||
menuBarMenu.append(new MenuItem({type: "separator"}))
|
||||
menuBarMenu.append(new MenuItem({
|
||||
click: cfu,
|
||||
label: "Check for updates"
|
||||
}))
|
||||
menuBarMenu.append(new MenuItem({role: "quit"}))
|
||||
TRAY.setContextMenu(menuBarMenu)
|
||||
}
|
||||
|
||||
cfu = () => require('../util/updateChecker').checkForUpdate(true, true)
|
||||
22
src/tray/showAbout.js
Normal file
@@ -0,0 +1,22 @@
|
||||
const path = require('path')
|
||||
const {BrowserWindow} = require('electron')
|
||||
|
||||
exports.run = () => {
|
||||
var aboutWindow = new BrowserWindow({
|
||||
center: true,
|
||||
maximizable: false,
|
||||
minimizable: false,
|
||||
resizable: false,
|
||||
width: 400,
|
||||
height: 600,
|
||||
alwaysOnTop: true
|
||||
})
|
||||
|
||||
aboutWindow.setMenu(null)
|
||||
|
||||
aboutWindow.loadURL("file://" + path.join(__dirname, "../windows/about.html"))
|
||||
|
||||
aboutWindow.on('close', () => {
|
||||
aboutWindow = null;
|
||||
})
|
||||
}
|
||||
31
src/tray/showPreferences.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const path = require('path')
|
||||
const {BrowserWindow} = require('electron')
|
||||
const os = require('os');
|
||||
let menuBarHeight
|
||||
|
||||
exports.run = () => {
|
||||
switch(os.platform()) {
|
||||
case "darwin":
|
||||
menuBarHeight = 440;
|
||||
break;
|
||||
default:
|
||||
menuBarHeight = 410;
|
||||
break;
|
||||
}
|
||||
|
||||
var settingsWindow = new BrowserWindow({
|
||||
center: true,
|
||||
maximizable: false,
|
||||
resizable: false,
|
||||
height: menuBarHeight,
|
||||
width: 400
|
||||
})
|
||||
|
||||
settingsWindow.setMenu(null)
|
||||
|
||||
settingsWindow.loadURL("file://" + path.join(__dirname, "../windows/preferences.html"))
|
||||
|
||||
settingsWindow.on('close', () => {
|
||||
settingsWindow = null;
|
||||
})
|
||||
}
|
||||
31
src/util/autoLaunch.js
Normal file
@@ -0,0 +1,31 @@
|
||||
//* Declare needed constants
|
||||
const {app} = require('electron')
|
||||
const chalk = require("chalk")
|
||||
const AutoLaunch = require('auto-launch')
|
||||
|
||||
//* Setup electron-config
|
||||
const Config = require('electron-config');
|
||||
const userSettings = new Config({
|
||||
name: "userSettings"
|
||||
});
|
||||
|
||||
if(userSettings.get('autoLaunch') == undefined || userSettings.get('autoLaunch') == true) {
|
||||
userSettings.set('autoLaunch', true)
|
||||
//* Add App to AutoLaunch
|
||||
console.log(CONSOLEPREFIX + chalk.yellow("Adding App to autostart..."))
|
||||
let autoLaunch = new AutoLaunch({
|
||||
name: 'PreMiD',
|
||||
path: app.getPath('exe'),
|
||||
isHidden: true
|
||||
});
|
||||
|
||||
//* Enable AutoLaunch if disabled
|
||||
autoLaunch.isEnabled().then(async (isEnabled) => {
|
||||
if (!isEnabled) autoLaunch.enable();
|
||||
console.log(CONSOLEPREFIX + chalk.green("Added App to autostart."))
|
||||
})
|
||||
//* Catch error
|
||||
.catch(function(err) {
|
||||
console.log(CONSOLEPREFIX + chalk.red("Error while adding App to autostart."))
|
||||
})
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
const chalk = require("chalk")
|
||||
const DiscordRPC = require("discord-rpc")
|
||||
|
||||
let app,
|
||||
consolePrefix,
|
||||
win,
|
||||
menuBar,
|
||||
menuBarMenu,
|
||||
chromeConnected,
|
||||
presenceReady,
|
||||
presence,
|
||||
setup,
|
||||
newVersion,
|
||||
introRan,
|
||||
lastResponse,
|
||||
ytmrpc,
|
||||
ytrpc,
|
||||
platform,
|
||||
data;
|
||||
|
||||
module.exports = {
|
||||
app: "",
|
||||
win: "",
|
||||
menuBar: "",
|
||||
menuBarMenu: "",
|
||||
chromeConnected: false,
|
||||
presenceReady: false,
|
||||
setup: false,
|
||||
presence: {
|
||||
details: "Waiting for music",
|
||||
state: "to start playing...",
|
||||
largeImageKey: "ytm_lg",
|
||||
instance: true
|
||||
},
|
||||
newVersion: false,
|
||||
introRan: false,
|
||||
lastResponse: false,
|
||||
ytmrpc: new DiscordRPC.Client({ transport: "ipc" }),
|
||||
ytrpc: new DiscordRPC.Client({ transport: "ipc" }),
|
||||
platform: "",
|
||||
data: ""
|
||||
};
|
||||
@@ -1,64 +1,60 @@
|
||||
var {app} = require('electron')
|
||||
if (require('electron-squirrel-startup')) return;
|
||||
|
||||
module.exports = {
|
||||
handleSquirrelEvent: function() {
|
||||
if (process.argv.length === 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ChildProcess = require('child_process');
|
||||
const path = require('path');
|
||||
|
||||
const appFolder = path.resolve(process.execPath, '..');
|
||||
const rootAtomFolder = path.resolve(appFolder, '..');
|
||||
const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe'));
|
||||
const exeName = path.basename(process.execPath);
|
||||
const spawn = function(command, args) {
|
||||
let spawnedProcess, error;
|
||||
|
||||
try {
|
||||
spawnedProcess = ChildProcess.spawn(command, args, {detached: true});
|
||||
} catch (error) {}
|
||||
|
||||
return spawnedProcess;
|
||||
};
|
||||
|
||||
const spawnUpdate = function(args) {
|
||||
return spawn(updateDotExe, args);
|
||||
};
|
||||
|
||||
const squirrelEvent = process.argv[1];
|
||||
const {app} = require('electron');
|
||||
|
||||
// this should be placed at top of main.js to handle setup events quickly
|
||||
if (handleSquirrelEvent()) {
|
||||
// squirrel event handled and app will exit in 1000ms, so don't do anything else
|
||||
return;
|
||||
}
|
||||
|
||||
function handleSquirrelEvent() {
|
||||
if (process.argv.length === 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ChildProcess = require('child_process');
|
||||
const path = require('path');
|
||||
|
||||
const appFolder = path.resolve(process.execPath, '..');
|
||||
const rootAtomFolder = path.resolve(appFolder, '..');
|
||||
const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe'));
|
||||
const exeName = path.basename(process.execPath);
|
||||
|
||||
const spawn = function(command, args) {
|
||||
let spawnedProcess, error;
|
||||
|
||||
try {
|
||||
spawnedProcess = ChildProcess.spawn(command, args, {detached: true});
|
||||
} catch (error) {}
|
||||
|
||||
return spawnedProcess;
|
||||
};
|
||||
|
||||
const spawnUpdate = function(args) {
|
||||
return spawn(updateDotExe, args);
|
||||
};
|
||||
|
||||
const squirrelEvent = process.argv[1];
|
||||
switch (squirrelEvent) {
|
||||
case '--squirrel-install':
|
||||
case '--squirrel-updated':
|
||||
// Optionally do things such as:
|
||||
// - Add your .exe to the PATH
|
||||
// - Write to the registry for things like file associations and
|
||||
// explorer context menus
|
||||
|
||||
// Install desktop and start menu shortcuts
|
||||
spawnUpdate(['--createShortcut', exeName]);
|
||||
|
||||
setTimeout(app.quit, 1000);
|
||||
return true;
|
||||
|
||||
case '--squirrel-uninstall':
|
||||
// Undo anything you did in the --squirrel-install and
|
||||
// --squirrel-updated handlers
|
||||
|
||||
// Remove desktop and start menu shortcuts
|
||||
spawnUpdate(['--removeShortcut', exeName]);
|
||||
|
||||
setTimeout(app.quit, 1000);
|
||||
return true;
|
||||
|
||||
case '--squirrel-obsolete':
|
||||
// This is called on the outgoing version of your app before
|
||||
// we update to the new version - it's the opposite of
|
||||
// --squirrel-updated
|
||||
|
||||
app.quit();
|
||||
return true;
|
||||
case '--squirrel-install':
|
||||
case '--squirrel-updated':
|
||||
|
||||
// Install desktop and start menu shortcuts
|
||||
spawnUpdate(['--createShortcut', exeName]);
|
||||
|
||||
setTimeout(app.quit, 1000);
|
||||
return true;
|
||||
|
||||
case '--squirrel-uninstall':
|
||||
// Remove desktop and start menu shortcuts
|
||||
spawnUpdate(['--removeShortcut', exeName]);
|
||||
|
||||
setTimeout(app.quit, 1000);
|
||||
return true;
|
||||
|
||||
case '--squirrel-obsolete':
|
||||
app.quit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
51
src/util/settingsHandler.js
Normal file
@@ -0,0 +1,51 @@
|
||||
const Config = require('electron-config');
|
||||
const userSettings = new Config({
|
||||
name: "userSettings"
|
||||
});
|
||||
|
||||
const {app} = require('electron')
|
||||
const AutoLaunch = require('auto-launch')
|
||||
|
||||
let autoLaunch = new AutoLaunch({
|
||||
name: 'PreMiD',
|
||||
path: app.getPath('exe'),
|
||||
isHidden: true
|
||||
});
|
||||
|
||||
var mediaControls = require('./shortcutHandler');
|
||||
|
||||
module.exports = async (data) => {
|
||||
if(userSettings.get('titleMenubar') != data.options.titleMenubar) {
|
||||
userSettings.set('titleMenubar', data.options.titleMenubar)
|
||||
if(PLATFORM == "darwin" && !data.options.titleMenubar) TRAY.setTitle("")
|
||||
}
|
||||
|
||||
if(userSettings.get('autoUpdateCheck') != data.options.checkForUpdates)
|
||||
userSettings.set('autoUpdateCheck', data.options.checkForUpdates)
|
||||
|
||||
if(userSettings.get('autoLaunch') != data.options.systemStartup) {
|
||||
userSettings.set('autoLaunch', data.options.systemStartup)
|
||||
|
||||
if(data.options.systemStartup) {
|
||||
autoLaunch.isEnabled().then(async (isEnabled) => {
|
||||
if (!isEnabled) autoLaunch.enable();
|
||||
})
|
||||
} else {
|
||||
autoLaunch.isEnabled().then(async (isEnabled) => {
|
||||
if (isEnabled) autoLaunch.disable();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if(userSettings.get('mediaControls') != data.options.mediaControls) {
|
||||
userSettings.set('mediaControls', data.options.mediaControls)
|
||||
if(data.options.mediaControls) mediaControls.register(); else mediaControls.unregister();
|
||||
}
|
||||
|
||||
if(userSettings.get('titleMenubar') != data.options.titleMenubar) {
|
||||
userSettings.set('titleMenubar', data.options.titleMenubar)
|
||||
if(!data.options.titleMenubar) TRAY.setTitle("")
|
||||
}
|
||||
|
||||
//console.log(data.options)
|
||||
}
|
||||
49
src/util/shortcutHandler.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const Config = require('electron-config');
|
||||
const userSettings = new Config({
|
||||
name: "userSettings"
|
||||
});
|
||||
|
||||
const chalk = require('chalk')
|
||||
var { globalShortcut, app } = require('electron')
|
||||
|
||||
module.exports.register = async () => {
|
||||
if(!userSettings.get('mediaControls')) return
|
||||
console.log(CONSOLEPREFIX + chalk.yellow("Registering keyboard shortcuts..."))
|
||||
|
||||
globalShortcut.register('medianexttrack', () => {
|
||||
if (EXTENSIONSOCKET != null) EXTENSIONSOCKET.emit('mediaKeyHandler', { playback: "nextTrack" })
|
||||
})
|
||||
|
||||
var pauseSkipToggle = 0;
|
||||
globalShortcut.register('mediaplaypause', () => {
|
||||
pauseSkipToggle++
|
||||
setTimeout(() => {
|
||||
if (EXTENSIONSOCKET != null && pauseSkipToggle == 1) EXTENSIONSOCKET.emit('mediaKeyHandler', { playback: "pause" })
|
||||
if (EXTENSIONSOCKET != null && pauseSkipToggle == 2) EXTENSIONSOCKET.emit('mediaKeyHandler', { playback: "nextTrack" })
|
||||
if (EXTENSIONSOCKET != null && pauseSkipToggle == 3) EXTENSIONSOCKET.emit('mediaKeyHandler', { playback: "previousTrack" })
|
||||
pauseSkipToggle = 0
|
||||
}, 500)
|
||||
})
|
||||
|
||||
globalShortcut.register('mediaprevioustrack', () => {
|
||||
if (EXTENSIONSOCKET != null) EXTENSIONSOCKET.emit('mediaKeyHandler', { playback: "previousTrack" })
|
||||
})
|
||||
|
||||
console.log(CONSOLEPREFIX + chalk.green("Successfully registered keyboard shortcuts."))
|
||||
}
|
||||
|
||||
module.exports.unregister = async () => {
|
||||
console.log(CONSOLEPREFIX + chalk.red("Unregistering keyboard shortcuts..."))
|
||||
if(require('os').platform() == "darwin") {
|
||||
app.relaunch()
|
||||
app.exit(0)
|
||||
} else
|
||||
globalShortcut.unregisterAll()
|
||||
console.log(CONSOLEPREFIX + chalk.green("Unregistered keyboard shortcuts"))
|
||||
}
|
||||
|
||||
app.on('will-quit', () => {
|
||||
console.log(CONSOLEPREFIX + chalk.red("Unregistering keyboard shortcuts..."))
|
||||
globalShortcut.unregisterAll()
|
||||
console.log(CONSOLEPREFIX + chalk.green("Unregistered keyboard shortcuts"))
|
||||
})
|
||||
@@ -1,9 +1,9 @@
|
||||
const { Notification } = require('electron');
|
||||
const { Notification, BrowserWindow } = require('electron');
|
||||
|
||||
const path = require('path')
|
||||
|
||||
const request = require("request")
|
||||
const chalk = require("chalk")
|
||||
let constants = require('./constants')
|
||||
let config = require('../config')
|
||||
|
||||
function checkForUpdate(sendNotification = false, sendNoUpdateInfo = false) {
|
||||
|
||||
@@ -14,20 +14,46 @@ function checkForUpdate(sendNotification = false, sendNoUpdateInfo = false) {
|
||||
json: true,
|
||||
headers: {'user-agent': 'node.js'}
|
||||
}, function (error, response, body) {
|
||||
if(error) {
|
||||
console.log(CONSOLEPREFIX + chalk.red("Error while checking for update. " + error))
|
||||
return
|
||||
}
|
||||
//* Remove v from version
|
||||
var gitVersion = body.tag_name.replace('v', '')
|
||||
//* Compare version
|
||||
if(gitVersion > VERSION) {
|
||||
global.UPDATEAVAIABLE = gitVersion
|
||||
constants.newVersion = gitVersion
|
||||
|
||||
console.log(CONSOLEPREFIX + chalk.cyan("New version avaiable: ") + chalk.red(`V${VERSION}`) + chalk.blue(' > ') + chalk.yellow(`V${gitVersion}`))
|
||||
|
||||
var updateWindow = new BrowserWindow({
|
||||
center: true,
|
||||
maximizable: false,
|
||||
minimizable: false,
|
||||
height: 500,
|
||||
minHeight: 500,
|
||||
width: 400,
|
||||
minWidth: 400,
|
||||
alwaysOnTop: true
|
||||
})
|
||||
|
||||
updateWindow.setMenu(null)
|
||||
|
||||
updateWindow.loadURL("file://" + path.join(__dirname, "../windows/update.html"))
|
||||
updateWindow.webContents.on('did-finish-load', () => {
|
||||
updateWindow.webContents.send('updateData', body);
|
||||
});
|
||||
|
||||
updateWindow.on('close', () => {
|
||||
updateWindow = null;
|
||||
})
|
||||
|
||||
} else {
|
||||
global.UPDATEAVAIABLE = false
|
||||
console.log(CONSOLEPREFIX + chalk.cyan("Up to date! ") + chalk.yellow(`V${VERSION}`))
|
||||
if(sendNoUpdateInfo) {
|
||||
const noUpdateAvaiableNotification = new Notification({
|
||||
title: 'Updater | YT Presence',
|
||||
title: 'PreMiD',
|
||||
body: `You are up to date! (V${VERSION})`,
|
||||
silent: true
|
||||
})
|
||||
@@ -37,23 +63,7 @@ function checkForUpdate(sendNotification = false, sendNoUpdateInfo = false) {
|
||||
}
|
||||
})
|
||||
|
||||
//* If sendNotification
|
||||
if(sendNotification && UPDATEAVAIABLE != false) {
|
||||
const updateNotification = new Notification({
|
||||
title: 'Updater | YT Presence',
|
||||
body: `Update avaiable! (V${UPDATEAVAIABLE})\nClick here to download the newest version.`,
|
||||
silent: true
|
||||
})
|
||||
|
||||
updateNotification.show()
|
||||
updateNotification.on('click', () => {
|
||||
require("electron").shell.openExternal("https://github.com/Timeraa/YT-Presence/releases/latest")
|
||||
})
|
||||
|
||||
return UPDATEAVAIABLE
|
||||
} else {
|
||||
return UPDATEAVAIABLE
|
||||
}
|
||||
return UPDATEAVAIABLE
|
||||
}
|
||||
|
||||
module.exports.checkForUpdate = checkForUpdate
|
||||
@@ -60,12 +60,10 @@ input:focus + .slider {
|
||||
}
|
||||
|
||||
input:hover + .slider {
|
||||
transform: scale(1.25);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(20px);
|
||||
-ms-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
47
src/windows/css/reset.css
Normal file
@@ -0,0 +1,47 @@
|
||||
@font-face {
|
||||
font-family: "Montserrat";
|
||||
src: url("../fonts/Montserrat/Montserrat-Regular.ttf") format("truetype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Montserrat";
|
||||
src: url("../fonts/Montserrat/Montserrat-Medium.ttf") format("truetype");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Montserrat";
|
||||
src: url("../fonts/Montserrat/Montserrat-Bold.ttf") format("truetype");
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Montserrat";
|
||||
src: url("../fonts/Montserrat/Montserrat-Black.ttf") format("truetype");
|
||||
font-weight: 900;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Montserrat";
|
||||
src: url("../fonts/Montserrat/Montserrat-BlackItalic.ttf") format("truetype");
|
||||
font-weight: 900;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "Montserrat", sans-serif;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||