Compare commits
872 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c7fee9f6d | ||
|
|
e9a245b144 | ||
|
|
2eb2514e74 | ||
|
|
7e69bf8ac3 | ||
|
|
53dbe582ac | ||
|
|
30e94a8964 | ||
|
|
c89bfcd4f9 | ||
|
|
ed3bbc5032 | ||
|
|
855618d926 | ||
|
|
26fcdc4b6e | ||
|
|
7e9b5582c0 | ||
|
|
a850aba829 | ||
|
|
e672acac43 | ||
|
|
0e39061f1b | ||
|
|
c0ed81298d | ||
|
|
dffed32515 | ||
|
|
a679908c6b | ||
|
|
63fac649d9 | ||
|
|
78a78340a0 | ||
|
|
1f1f3efb43 | ||
|
|
4bc8ea068e | ||
|
|
a85b73b935 | ||
|
|
e4b01de2b5 | ||
|
|
b21be7d2c9 | ||
|
|
d410c4699b | ||
|
|
e7b259f764 | ||
|
|
0405098dcc | ||
|
|
6aa7b2afe7 | ||
|
|
255edefa03 | ||
|
|
32e8538e88 | ||
|
|
5bb697bb85 | ||
|
|
46d8e1ecf5 | ||
|
|
53e4615a7a | ||
|
|
7b9eae280d | ||
|
|
e5934f9e85 | ||
|
|
26fae1dd06 | ||
|
|
c0aaba73de | ||
|
|
e849d230e7 | ||
|
|
2c23822ace | ||
|
|
342e44a20f | ||
|
|
121891f825 | ||
|
|
1da64adca1 | ||
|
|
96c8fecb9d | ||
|
|
178858d67c | ||
|
|
18b2899b25 | ||
|
|
8f6c324267 | ||
|
|
9fad4423f4 | ||
|
|
f82f03a06f | ||
|
|
73b82b12a7 | ||
|
|
f49c9ea60d | ||
|
|
f0c53c54b7 | ||
|
|
ab2547cfa0 | ||
|
|
496512f84c | ||
|
|
b954427f1a | ||
|
|
aaebe5e65f | ||
|
|
7fc6cefba1 | ||
|
|
a30ed090c4 | ||
|
|
d60d22d0ec | ||
|
|
890cf02a5e | ||
|
|
af68656310 | ||
|
|
21203685ba | ||
|
|
9caca125d0 | ||
|
|
cb182ac1b2 | ||
|
|
58bebf1b33 | ||
|
|
0ee1d67122 | ||
|
|
e44da5e088 | ||
|
|
18e2801bf8 | ||
|
|
c0dc7fec56 | ||
|
|
2ceba8a949 | ||
|
|
a4b9a1f415 | ||
|
|
3bb7e12a1c | ||
|
|
1704c31a85 | ||
|
|
65cf34b3e0 | ||
|
|
c17e9238a7 | ||
|
|
e56d281631 | ||
|
|
0361dbe153 | ||
|
|
25f0ed2b29 | ||
|
|
ddae09fe85 | ||
|
|
ac9b1369da | ||
|
|
7422c27c7d | ||
|
|
ccc133046c | ||
|
|
bf0e4abece | ||
|
|
e7abd2bebe | ||
|
|
a18ec8a20f | ||
|
|
4b58daac14 | ||
|
|
e76c1ecaf1 | ||
|
|
df4a4b1dce | ||
|
|
028f155268 | ||
|
|
0ccf272a1a | ||
|
|
b2442b3702 | ||
|
|
47d50d0500 | ||
|
|
7c69006e60 | ||
|
|
38bd00212e | ||
|
|
f3a1c5f569 | ||
|
|
6961907eec | ||
|
|
5b66cdd8d4 | ||
|
|
06d5a08dd0 | ||
|
|
6cf14a099b | ||
|
|
93cee61bfb | ||
|
|
82c8262a2c | ||
|
|
b455c5aa2c | ||
|
|
df352a53bc | ||
|
|
2546d38fce | ||
|
|
68984fa817 | ||
|
|
804ff2d2c7 | ||
|
|
da5db665eb | ||
|
|
a457a69c21 | ||
|
|
0d4fb97292 | ||
|
|
b39fa254b9 | ||
|
|
8e7996424c | ||
|
|
2b10984921 | ||
|
|
ba6cb75501 | ||
|
|
d792a73dcf | ||
|
|
dc3477b4cd | ||
|
|
45655ed3cc | ||
|
|
e0a0048d39 | ||
|
|
39c842c026 | ||
|
|
d4e3b4d40f | ||
|
|
7aac2586ef | ||
|
|
fe56d63258 | ||
|
|
79d05914bd | ||
|
|
cb336f47fe | ||
|
|
c95d54c2e9 | ||
|
|
0b47b11601 | ||
|
|
eed3895f1b | ||
|
|
fd6c4d0bf6 | ||
|
|
e50d5a4a88 | ||
|
|
7770fb81d1 | ||
|
|
bd4fcaf2f9 | ||
|
|
297e174a84 | ||
|
|
71c704588d | ||
|
|
26b2ac1830 | ||
|
|
266988327f | ||
|
|
58b55bf2ba | ||
|
|
df0f9e01bc | ||
|
|
d6cc83a8ff | ||
|
|
44f23d804d | ||
|
|
cc06e52488 | ||
|
|
a6fe077d88 | ||
|
|
df39ea19e7 | ||
|
|
2f455d03f5 | ||
|
|
98c1de387d | ||
|
|
53d185bf9c | ||
|
|
0ef3987956 | ||
|
|
a7ce1d1468 | ||
|
|
9cc2942a49 | ||
|
|
4ffe34c538 | ||
|
|
22b12073f9 | ||
|
|
83489fff84 | ||
|
|
2511dd5b4e | ||
|
|
767bd08f0c | ||
|
|
d2ba2ff544 | ||
|
|
f6ad1226f5 | ||
|
|
785b0d7395 | ||
|
|
ea91a55bd6 | ||
|
|
c73f13baa8 | ||
|
|
a44c68ef46 | ||
|
|
218627e62d | ||
|
|
5d6e775b02 | ||
|
|
2b86cff3f3 | ||
|
|
0bc70dbc9e | ||
|
|
d1f7baad2b | ||
|
|
6d57bc2c5a | ||
|
|
8e3cf93011 | ||
|
|
51f6d17fbb | ||
|
|
b2e5229c78 | ||
|
|
87ec87e09d | ||
|
|
25bf7ac915 | ||
|
|
bcadad5564 | ||
|
|
bacda4624f | ||
|
|
9c5434e32c | ||
|
|
058421b9aa | ||
|
|
f947f50213 | ||
|
|
54688e6a71 | ||
|
|
d789bd7710 | ||
|
|
b3fa69f7c7 | ||
|
|
3ec47b2310 | ||
|
|
9bc37d8ecd | ||
|
|
dd21c46331 | ||
|
|
3c69cf7d5a | ||
|
|
97f8a0faf6 | ||
|
|
ce8b6dc995 | ||
|
|
d78eebdb0e | ||
|
|
01f78e0595 | ||
|
|
fc8e710a07 | ||
|
|
929131f5e6 | ||
|
|
4fbb0e454e | ||
|
|
3832a8811d | ||
|
|
8f6461e80f | ||
|
|
e21e12820b | ||
|
|
1edff1048f | ||
|
|
8e71e6b0ea | ||
|
|
1efd3dbea9 | ||
|
|
d02ad5a5b6 | ||
|
|
8758047ff0 | ||
|
|
c17df3c2b6 | ||
|
|
fe54d6537f | ||
|
|
dcc3516587 | ||
|
|
7039296c64 | ||
|
|
cdba36628f | ||
|
|
b2465f9bdc | ||
|
|
4b4a398c99 | ||
|
|
d292bd033f | ||
|
|
faa5683b26 | ||
|
|
ce0ae1bf04 | ||
|
|
b8f49b9312 | ||
|
|
7b9bcdfd10 | ||
|
|
72d65a18ef | ||
|
|
160a008a0b | ||
|
|
030f5ed315 | ||
|
|
018051572c | ||
|
|
fc2d1ffaca | ||
|
|
418eb81e1c | ||
|
|
5c2c576cb4 | ||
|
|
9cf11bf2d9 | ||
|
|
a050d220d0 | ||
|
|
5e64d55ac0 | ||
|
|
d32a657d62 | ||
|
|
78e5e298b3 | ||
|
|
44ad0f3a51 | ||
|
|
e783cc64f5 | ||
|
|
c1f10a1c46 | ||
|
|
a0231ed598 | ||
|
|
900ba2f3a2 | ||
|
|
519e224914 | ||
|
|
2e067f98ff | ||
|
|
63ca296037 | ||
|
|
2221053c66 | ||
|
|
5ce6354bd3 | ||
|
|
44ae334492 | ||
|
|
4020de976f | ||
|
|
9929a5f578 | ||
|
|
3dd1e916c1 | ||
|
|
5b810e8cf5 | ||
|
|
a9356fbd4a | ||
|
|
6aad9e6130 | ||
|
|
258b4113db | ||
|
|
66d5b7a6f4 | ||
|
|
4c4df5011e | ||
|
|
2b99b888bc | ||
|
|
618e1f64df | ||
|
|
fca00e7084 | ||
|
|
7d92df6626 | ||
|
|
f00b552305 | ||
|
|
d7b5f5f25b | ||
|
|
a4c3088e02 | ||
|
|
0e44df8cfa | ||
|
|
eddc2214ed | ||
|
|
db3f87d219 | ||
|
|
d962124da2 | ||
|
|
e1c8afd5ba | ||
|
|
01614667a4 | ||
|
|
43bd4ff468 | ||
|
|
d5bdb78de6 | ||
|
|
acd5e547fd | ||
|
|
201eb38a35 | ||
|
|
9b13c2554a | ||
|
|
21918cadd9 | ||
|
|
55191a6e9b | ||
|
|
e93a30d2e1 | ||
|
|
443fce9fd1 | ||
|
|
02f4a730c7 | ||
|
|
f02626a118 | ||
|
|
7632219a83 | ||
|
|
4e563b3c05 | ||
|
|
92a60bd03e | ||
|
|
1238ef62fa | ||
|
|
0a101e3b69 | ||
|
|
ecd2f0e0f2 | ||
|
|
9be3cc1f13 | ||
|
|
c64c503ba9 | ||
|
|
d704b2ecac | ||
|
|
66539aa422 | ||
|
|
f8c20e55a4 | ||
|
|
3b5448a334 | ||
|
|
4b1614e247 | ||
|
|
bb4f843a33 | ||
|
|
9008039a2a | ||
|
|
fb1ee381fe | ||
|
|
8ad0ce8911 | ||
|
|
59c4b6db86 | ||
|
|
f4e15215ec | ||
|
|
b57cc559d9 | ||
|
|
4a1d6047ac | ||
|
|
3d411826f2 | ||
|
|
898c0a2f7c | ||
|
|
2a9bc2278d | ||
|
|
989209758a | ||
|
|
1d4386e9e9 | ||
|
|
d8e45814bb | ||
|
|
ce01f8bce0 | ||
|
|
76384e38c8 | ||
|
|
ac64512ff7 | ||
|
|
7d9261dace | ||
|
|
6187b849a7 | ||
|
|
724d0b2567 | ||
|
|
2d24e2e0eb | ||
|
|
d4d65044b3 | ||
|
|
717f1e7eec | ||
|
|
30b58d213e | ||
|
|
0404b5f1e4 | ||
|
|
f2a946790d | ||
|
|
37ea2260b8 | ||
|
|
938ad5f8b9 | ||
|
|
4e881415d2 | ||
|
|
96af470708 | ||
|
|
3275abafb0 | ||
|
|
2538a41fcb | ||
|
|
d93b76a664 | ||
|
|
ea5703d99d | ||
|
|
22c3c797ff | ||
|
|
0cc0ec6c55 | ||
|
|
d1e5fdc1e0 | ||
|
|
ed9c5a0dc7 | ||
|
|
e1fae2e219 | ||
|
|
e5cf24e1cc | ||
|
|
3d1f970262 | ||
|
|
a002655b3d | ||
|
|
9fe2384b47 | ||
|
|
a6781414a5 | ||
|
|
cbdbac4e01 | ||
|
|
c867e62502 | ||
|
|
341fe5d46e | ||
|
|
e70eefdbbf | ||
|
|
67c2daf4ef | ||
|
|
178cfd4a6b | ||
|
|
6d868e21da | ||
|
|
691a6d0956 | ||
|
|
6eda60d314 | ||
|
|
41b0896c2e | ||
|
|
e8bdeed556 | ||
|
|
c29dd321e3 | ||
|
|
6062534d91 | ||
|
|
d6bb61c428 | ||
|
|
65a56684ec | ||
|
|
e1dfe30661 | ||
|
|
87cb1cc4f7 | ||
|
|
0be75ca38e | ||
|
|
54b2561da1 | ||
|
|
fbba7a30d0 | ||
|
|
42d361b7ad | ||
|
|
6d41e6b962 | ||
|
|
ed32aad64a | ||
|
|
e4896fe935 | ||
|
|
2f81690783 | ||
|
|
dc3ec24cd7 | ||
|
|
797171fc3a | ||
|
|
16e12a8a7b | ||
|
|
0e07124cbc | ||
|
|
5db66e3fcb | ||
|
|
01770d25f8 | ||
|
|
e4366c8dfa | ||
|
|
f19446eda9 | ||
|
|
0d7f1657de | ||
|
|
e905f01305 | ||
|
|
e5e7fa3f8a | ||
|
|
69575622a2 | ||
|
|
ee229e9ed8 | ||
|
|
21a9481459 | ||
|
|
f28732904d | ||
|
|
06828e2cfd | ||
|
|
e89c58e2e9 | ||
|
|
cb1203a2b8 | ||
|
|
be64aba265 | ||
|
|
316281d42b | ||
|
|
91520753b0 | ||
|
|
94bb94e8f4 | ||
|
|
fcf020658a | ||
|
|
4d8cd8a926 | ||
|
|
ec871c1a41 | ||
|
|
acf7fe3117 | ||
|
|
55f99980cc | ||
|
|
7079cc0d20 | ||
|
|
dfb68c512b | ||
|
|
85ff73c055 | ||
|
|
96bb31de5f | ||
|
|
b06f13e32a | ||
|
|
512282c446 | ||
|
|
0986583365 | ||
|
|
7e5c07c6e5 | ||
|
|
99d14139d2 | ||
|
|
b5419ee747 | ||
|
|
22e9f3308b | ||
|
|
d1161207da | ||
|
|
f8aad34bb1 | ||
|
|
8b9686edba | ||
|
|
e0e8a66d48 | ||
|
|
6d029505ed | ||
|
|
e5c7c4b02f | ||
|
|
a17bbc4d15 | ||
|
|
bc5c9df40d | ||
|
|
59c5dfe703 | ||
|
|
953e2e6a73 | ||
|
|
f16b3cb2dd | ||
|
|
b8d5978668 | ||
|
|
6dc2d5092d | ||
|
|
45227c6628 | ||
|
|
76f88ffd66 | ||
|
|
5a6864f26e | ||
|
|
8eca4c8054 | ||
|
|
1a12ce8992 | ||
|
|
db8d6ce4ab | ||
|
|
9874c5f417 | ||
|
|
9f2e4277bb | ||
|
|
2d933416f8 | ||
|
|
6886f3081f | ||
|
|
3edbbda7fa | ||
|
|
7e7160e0bf | ||
|
|
a9f92dc9f3 | ||
|
|
57d6da52bb | ||
|
|
72dc85d90d | ||
|
|
ff5ff54e88 | ||
|
|
6ab0fa3fbd | ||
|
|
4d4c02ebb3 | ||
|
|
a34542171c | ||
|
|
fce6138031 | ||
|
|
38c8197989 | ||
|
|
b7f4578c34 | ||
|
|
e5ea72e334 | ||
|
|
73a0f610c3 | ||
|
|
ee2d884434 | ||
|
|
a9ac568dc0 | ||
|
|
365dac5c2b | ||
|
|
511069b641 | ||
|
|
342d3bbd49 | ||
|
|
28da67c0c5 | ||
|
|
47c9de2e22 | ||
|
|
9e6f8c16a5 | ||
|
|
1f8d3aa7f4 | ||
|
|
209c16eff8 | ||
|
|
49b0135798 | ||
|
|
1d55dad4b1 | ||
|
|
f4e9434294 | ||
|
|
97cf766466 | ||
|
|
debcd3dc0d | ||
|
|
495d7ba9aa | ||
|
|
aac405a99d | ||
|
|
22fed1dfba | ||
|
|
ce79a638f5 | ||
|
|
ae420910e9 | ||
|
|
8068d4e591 | ||
|
|
cd3a7375e6 | ||
|
|
be9f60abf3 | ||
|
|
6431afec31 | ||
|
|
43c744df59 | ||
|
|
116d7b4365 | ||
|
|
a4fd51445d | ||
|
|
66393224ba | ||
|
|
8faceb1376 | ||
|
|
3ce0379c99 | ||
|
|
24a8dfdfdb | ||
|
|
3952044a82 | ||
|
|
a11128ae9f | ||
|
|
ca802a7254 | ||
|
|
ae7d4770fa | ||
|
|
430c00c689 | ||
|
|
302f7018d4 | ||
|
|
804445637d | ||
|
|
e9d1718793 | ||
|
|
d9953ff0ac | ||
|
|
5433bf013d | ||
|
|
244cbb39ca | ||
|
|
a0eac8e0dc | ||
|
|
f8c473d039 | ||
|
|
fc259f5c20 | ||
|
|
a3a6ec4838 | ||
|
|
c32a8c1614 | ||
|
|
50f4e623f7 | ||
|
|
b7de63c5f5 | ||
|
|
4ed41cf06a | ||
|
|
d613ceb3eb | ||
|
|
91ee57997b | ||
|
|
50a7a94dac | ||
|
|
61c5d7e637 | ||
|
|
816ba32bb0 | ||
|
|
3c6937ea94 | ||
|
|
bf897eb02a | ||
|
|
254bb9e0a9 | ||
|
|
2cdd9a7fc0 | ||
|
|
774abcc612 | ||
|
|
bbea1fba25 | ||
|
|
1c68b02343 | ||
|
|
1f2054beb7 | ||
|
|
2385942f7c | ||
|
|
36bef805ea | ||
|
|
ed1f88db9d | ||
|
|
c4390a0bb0 | ||
|
|
301e761897 | ||
|
|
72173298e3 | ||
|
|
c4265edaf4 | ||
|
|
93f9bde307 | ||
|
|
0bf8f978f9 | ||
|
|
a6522bbcf2 | ||
|
|
44aeddcdbd | ||
|
|
c6a630875f | ||
|
|
b18fa8fa76 | ||
|
|
689808a9db | ||
|
|
8bb45d6f43 | ||
|
|
cd1ff1699b | ||
|
|
4ca13ca884 | ||
|
|
b05138630a | ||
|
|
9394ac47f4 | ||
|
|
c43716b0d9 | ||
|
|
e8b54ddc1f | ||
|
|
37d756b1b0 | ||
|
|
e3140aaab8 | ||
|
|
238aa2e509 | ||
|
|
54c6d4fb96 | ||
|
|
969b921fae | ||
|
|
40add5ca44 | ||
|
|
06db4610ca | ||
|
|
e4334f256a | ||
|
|
4286baec0f | ||
|
|
cd1df94235 | ||
|
|
649b73f0e1 | ||
|
|
e967d4b344 | ||
|
|
e5a71b8044 | ||
|
|
9886957034 | ||
|
|
3e7d155002 | ||
|
|
b96add529c | ||
|
|
e91db6aeec | ||
|
|
1b25283284 | ||
|
|
2bc61baac3 | ||
|
|
f862f1a2c4 | ||
|
|
3074169446 | ||
|
|
afee575f10 | ||
|
|
94a53a278c | ||
|
|
4a3ac7176f | ||
|
|
305c5bad68 | ||
|
|
4570da2e26 | ||
|
|
7ec0487e37 | ||
|
|
3aa3dccda7 | ||
|
|
21efa7f639 | ||
|
|
614fd1a85d | ||
|
|
05bd6a5d48 | ||
|
|
208fa85e8f | ||
|
|
2b703cac3a | ||
|
|
ce59872a66 | ||
|
|
c402c416e5 | ||
|
|
466b4314c5 | ||
|
|
40f8aac655 | ||
|
|
2afd1ab938 | ||
|
|
722fcaa2e1 | ||
|
|
5d3830d3de | ||
|
|
da244fe836 | ||
|
|
c00ff163f1 | ||
|
|
6bb18f18fd | ||
|
|
b8ea8f8a97 | ||
|
|
f9c01d03d3 | ||
|
|
f05dcf99ff | ||
|
|
a8edec2184 | ||
|
|
de3db81222 | ||
|
|
e0a49bc71e | ||
|
|
031e65efa7 | ||
|
|
3a1978e2fe | ||
|
|
edffa28d89 | ||
|
|
2c60fadb99 | ||
|
|
adfd9f63fa | ||
|
|
22f3f245b5 | ||
|
|
53e832fbf0 | ||
|
|
884c180e43 | ||
|
|
a1d5c0252d | ||
|
|
94a40f4b79 | ||
|
|
523467f47e | ||
|
|
eea48c257f | ||
|
|
d9e6718217 | ||
|
|
84afda69c0 | ||
|
|
820a1c1604 | ||
|
|
941d79410b | ||
|
|
78d2b8a68b | ||
|
|
0d147c7585 | ||
|
|
2f23d6a67d | ||
|
|
df6c5fee9c | ||
|
|
41f6bc588c | ||
|
|
660eedb917 | ||
|
|
37cc205dfa | ||
|
|
78beaf0b45 | ||
|
|
8c5cb09e70 | ||
|
|
3163e53502 | ||
|
|
1a58cdb08f | ||
|
|
183ebfad96 | ||
|
|
49e7e14422 | ||
|
|
6576099748 | ||
|
|
5d6bc5bc55 | ||
|
|
edf0c62ce3 | ||
|
|
0a9f3efecc | ||
|
|
a7bc98d1e3 | ||
|
|
ac03bc50b7 | ||
|
|
61a8d07912 | ||
|
|
2d744f1080 | ||
|
|
2582fe20db | ||
|
|
6a322ef9d5 | ||
|
|
bbcbd55e5a | ||
|
|
99f6e1b346 | ||
|
|
a7c564ee20 | ||
|
|
bf9b6f634c | ||
|
|
1698c9311b | ||
|
|
6b7c2c6f01 | ||
|
|
54e52758e5 | ||
|
|
4f9a85b3a7 | ||
|
|
7fe63a2cfe | ||
|
|
a7c418ac79 | ||
|
|
3a51ce523c | ||
|
|
ff0f8bd86e | ||
|
|
12d4b1448d | ||
|
|
3e552f19b5 | ||
|
|
13e2ce88d5 | ||
|
|
276814f2d8 | ||
|
|
4263c59117 | ||
|
|
786e1441d7 | ||
|
|
4100673705 | ||
|
|
759d4475fc | ||
|
|
2e986a4bdd | ||
|
|
005afae9aa | ||
|
|
739cdea934 | ||
|
|
894e774523 | ||
|
|
397a3f5d80 | ||
|
|
c30c6a4cfb | ||
|
|
01134c94b8 | ||
|
|
0cd963a9cf | ||
|
|
1db452829d | ||
|
|
9e7d0d7429 | ||
|
|
de891f783f | ||
|
|
dd4922ea77 | ||
|
|
e0ac7022fc | ||
|
|
0809c80965 | ||
|
|
1e5e8ef5fc | ||
|
|
bc44ee346a | ||
|
|
2ed9a55c9b | ||
|
|
88196afc14 | ||
|
|
60605eb347 | ||
|
|
d361621dc3 | ||
|
|
1e99b7ffa2 | ||
|
|
143e02d16c | ||
|
|
92cb18389e | ||
|
|
ce4383505c | ||
|
|
6e0ab7f24d | ||
|
|
64461d649b | ||
|
|
19acd42336 | ||
|
|
5d050348ea | ||
|
|
6d34e8e9bb | ||
|
|
5a80658ec5 | ||
|
|
be3ba2219a | ||
|
|
00026ee452 | ||
|
|
706e381f02 | ||
|
|
d06655316b | ||
|
|
17308694d8 | ||
|
|
ef7dfa7709 | ||
|
|
871ece2514 | ||
|
|
106ea10d93 | ||
|
|
5398b98195 | ||
|
|
4caef40690 | ||
|
|
a7ab6f11fb | ||
|
|
41b1d68de6 | ||
|
|
c322c8818b | ||
|
|
6a2de3a9a7 | ||
|
|
f40c52d317 | ||
|
|
c2774fc562 | ||
|
|
bad7fd1234 | ||
|
|
3bc2227f70 | ||
|
|
8c2c25ad52 | ||
|
|
0dc4511f0f | ||
|
|
3cdf057be5 | ||
|
|
727e11996c | ||
|
|
7259154e0c | ||
|
|
8e5212b37a | ||
|
|
b09b4929ea | ||
|
|
5629bb63c0 | ||
|
|
2c100466c4 | ||
|
|
a963567d95 | ||
|
|
6f9b1586bf | ||
|
|
3076ed37dd | ||
|
|
38fe1c60f6 | ||
|
|
fc551a7acd | ||
|
|
1e974807e5 | ||
|
|
0dc258ebde | ||
|
|
b26e92ecb7 | ||
|
|
6488a62c45 | ||
|
|
cf3825be83 | ||
|
|
a4bb14d1a0 | ||
|
|
a5e431e31c | ||
|
|
4005f2c6de | ||
|
|
b0b9be552b | ||
|
|
acacdc870a | ||
|
|
66a89572ca | ||
|
|
a12c817821 | ||
|
|
d19912ff5b | ||
|
|
111ede487d | ||
|
|
6f7ca3cb5e | ||
|
|
e6b63095ad | ||
|
|
a40e8e3c57 | ||
|
|
0d129be808 | ||
|
|
d70ab1beab | ||
|
|
5666cbd9c0 | ||
|
|
b0d4eb7c3f | ||
|
|
ed5773883b | ||
|
|
fc668cb395 | ||
|
|
d7746c48f2 | ||
|
|
b5cb340a43 | ||
|
|
44089e28f7 | ||
|
|
1c6fb7f1ac | ||
|
|
4198b31cd7 | ||
|
|
638364d3d2 | ||
|
|
e7195e40b0 | ||
|
|
1e084234fd | ||
|
|
833813098d | ||
|
|
df0e27e56a | ||
|
|
5b8fbf8ea6 | ||
|
|
3286d38fc8 | ||
|
|
8838185cbf | ||
|
|
0be5bfd050 | ||
|
|
154b265e1f | ||
|
|
7a9e965cc2 | ||
|
|
e05a770f51 | ||
|
|
fd5e5ff7d4 | ||
|
|
53e73cc42a | ||
|
|
c419eef405 | ||
|
|
0c24ac38be | ||
|
|
67535d8691 | ||
|
|
1205d5d113 | ||
|
|
7be63d8e99 | ||
|
|
695cf18449 | ||
|
|
a117d42f67 | ||
|
|
a98dd3382c | ||
|
|
34e0755b78 | ||
|
|
975f8d81ce | ||
|
|
769b6465d1 | ||
|
|
12d3a781ff | ||
|
|
0bab251f3d | ||
|
|
8eb0d43287 | ||
|
|
44e69429ad | ||
|
|
d787de821a | ||
|
|
7c616718fd | ||
|
|
2edfab25d7 | ||
|
|
584fc6088e | ||
|
|
99254b3315 | ||
|
|
e5f3d86b9f | ||
|
|
0322aeada2 | ||
|
|
6d9ca8a820 | ||
|
|
c57f647ddd | ||
|
|
1f5669532f | ||
|
|
055d6a6790 | ||
|
|
9eb03f2c16 | ||
|
|
f6569f5091 | ||
|
|
cb0a632944 | ||
|
|
576c3cc7d2 | ||
|
|
8490e93b99 | ||
|
|
31d318b7d2 | ||
|
|
cd50872acb | ||
|
|
ff7ff8ee58 | ||
|
|
14d29dc167 | ||
|
|
99aa8579cd | ||
|
|
5df7be8fef | ||
|
|
4fbd56cf08 | ||
|
|
01f9ccdb4d | ||
|
|
c6749105e0 | ||
|
|
7a582a6576 | ||
|
|
dfab4af72c | ||
|
|
a200246843 | ||
|
|
89a6c467d4 | ||
|
|
a4bc108cdc | ||
|
|
d0f5b803fa | ||
|
|
10f1acc0ac | ||
|
|
10da4bc4e6 | ||
|
|
cb6d5865a4 | ||
|
|
fe19187dad | ||
|
|
024e9b247e | ||
|
|
d058940728 | ||
|
|
5ca16e8f1c | ||
|
|
d52ddfed36 | ||
|
|
b1ba8e4d6e | ||
|
|
2e9c5d3bac | ||
|
|
ac79d8482f | ||
|
|
597594b5bc | ||
|
|
7736259f70 | ||
|
|
f3558f4aa7 | ||
|
|
e6fa3dd823 | ||
|
|
c4b1502385 | ||
|
|
ccb75f4166 | ||
|
|
bc3932d008 | ||
|
|
9e29398b11 | ||
|
|
a0646862fc | ||
|
|
2085b0340f | ||
|
|
1550997d55 | ||
|
|
18f6c24809 | ||
|
|
7c387140d4 | ||
|
|
91765df50d | ||
|
|
ac4cd8f5c6 | ||
|
|
27ef9efb38 | ||
|
|
874dd9ff62 | ||
|
|
a3cce7edcd | ||
|
|
1ac98acefd | ||
|
|
9370a9331b | ||
|
|
cfe2522699 | ||
|
|
ee9bd8dd1a | ||
|
|
532ac4f8a7 | ||
|
|
1859fce603 | ||
|
|
452c1da6b8 | ||
|
|
75569abbe2 | ||
|
|
0ce772a6d6 | ||
|
|
92c28368f6 | ||
|
|
216228d9e4 | ||
|
|
c13145971a | ||
|
|
c78e90588a | ||
|
|
8e3b7b0418 | ||
|
|
f3eac47dc7 | ||
|
|
bf7304df3b | ||
|
|
c5ddf1a1c7 | ||
|
|
de951e3ea0 | ||
|
|
44b7e34d7f | ||
|
|
e025496bbc | ||
|
|
db747ea246 | ||
|
|
84c1110f18 | ||
|
|
73253cda17 | ||
|
|
34f6ac59f6 | ||
|
|
da814b0a5a | ||
|
|
99421e7617 | ||
|
|
c30eb02d91 | ||
|
|
59185b6112 | ||
|
|
79c070ec0d | ||
|
|
ce4b1c8014 | ||
|
|
3d3d44440a | ||
|
|
a91f7126e1 | ||
|
|
d9358b6134 | ||
|
|
fd4cdcaba6 | ||
|
|
13fd612b50 | ||
|
|
905872232d | ||
|
|
409fa79f59 | ||
|
|
82304058b2 | ||
|
|
ec457a0e44 | ||
|
|
f176938831 | ||
|
|
33c5a40e9f | ||
|
|
57874362c3 | ||
|
|
c1581f3845 | ||
|
|
72d510a6c1 | ||
|
|
723233be84 | ||
|
|
ad9a0b2f50 | ||
|
|
b881ea1e03 | ||
|
|
e2fb3802d7 | ||
|
|
eb7674cf04 | ||
|
|
3ee169ba14 | ||
|
|
4a903053de | ||
|
|
961ad02e8a | ||
|
|
472a063979 | ||
|
|
4fd61c97df | ||
|
|
5b81c31ba2 | ||
|
|
ef9507a282 | ||
|
|
4efe137e82 | ||
|
|
cea5a282c2 | ||
|
|
2ad69bf1e9 | ||
|
|
397cfaf23a | ||
|
|
8223c073ef | ||
|
|
b564b5d0f6 | ||
|
|
c744f1ff93 | ||
|
|
39656bec03 | ||
|
|
5b1f7db2c5 | ||
|
|
f914026c14 | ||
|
|
156150bd36 | ||
|
|
99b7e83324 | ||
|
|
4222d98e49 | ||
|
|
cd00881afb | ||
|
|
d1cf1e4243 | ||
|
|
cf5227a81f | ||
|
|
2110fbee8d | ||
|
|
680116082b | ||
|
|
94092eb6af | ||
|
|
1286fb165c | ||
|
|
36a22bd5eb | ||
|
|
15fa4b80b2 | ||
|
|
2c5281a41c | ||
|
|
2e433d73db | ||
|
|
1f915c6c5e |
3
.devScript.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"outDir": "dist/app"
|
||||
}
|
||||
30
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# Contributing
|
||||
|
||||
## Requiered knowledge
|
||||
|
||||
- JavaScript
|
||||
- html5
|
||||
- NodeJS
|
||||
|
||||
Additional:
|
||||
|
||||
- CSS
|
||||
- [VueJS](https://vuejs.org/)
|
||||
- [ElectronJS](https://electronjs.org/)
|
||||
- [NPMjs](https://www.npmjs.com/)
|
||||
|
||||
A source code editor is also requiered. We recommend [Visual Studio Code](https://code.visualstudio.com/).
|
||||
|
||||
### Installing the components
|
||||
|
||||
1. Install [Git](https://git-scm.com/)
|
||||
2. Install [Node](https://nodejs.org/en/)
|
||||
|
||||
### Cloning the project
|
||||
|
||||
1. Fork the [repository](https://github.com/PreMiD/PreMiD)
|
||||
2. Open a terminal and type `git clone https://github.com/PreMiD/PreMiD`
|
||||
|
||||
### Coding your vision
|
||||
|
||||
Please keep the structure. We don't want to disorganize our project. Chaotic files may not be accepted.
|
||||
BIN
.github/Electron/Chrome_bsp.png
vendored
Normal file
|
After Width: | Height: | Size: 332 KiB |
BIN
.github/Electron/PMD_Banner.png
vendored
Normal file
|
After Width: | Height: | Size: 682 KiB |
12
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: Timeraa
|
||||
open_collective: premid
|
||||
ko_fi: timeraa
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZU8Q766ACS2WS&lc=US
|
||||
3
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for YT Presence
|
||||
|
||||
about: Suggest an idea for PreMiD
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
|
||||
16
.github/ISSUE_TEMPLATE/service_request.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: Service request
|
||||
about: Suggest Rich Presence support for a website
|
||||
---
|
||||
|
||||
**What's the name of the service?**
|
||||
Ex. www.youtube.com | YouTube
|
||||
|
||||
**What should the Presence display?**
|
||||
Informations about the current video
|
||||
|
||||
**Why do you want support for this service?**
|
||||
Tell us why you want to have support for this website. Please don't just tell us "I use it all the time"
|
||||
|
||||
**Are you able to provide an image for the service? (512x512 minimum)**
|
||||
If you can provide the logo pls paste a link in here or the image
|
||||
BIN
.github/Logo.png
vendored
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
.github/Patreon.png
vendored
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
1
.github/PayPal.svg
vendored
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
13
.github/SUPPORT.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# How to get support
|
||||
|
||||
## Take a look at the [wiki](https://wiki.premid.app)
|
||||
Our GitHub wiki is full of information around PreMiD.<br>
|
||||
Take a look and feel free to contribute if you want to add something new.
|
||||
|
||||
## [Open a issue](https://github.com/PreMiD/PreMiD/issues/new/choose) on [GitHub](https://github.com/PreMiD/PreMiD)
|
||||
Simply open a issue if you don't feel allright.<br>
|
||||
*Aand there he goes...*
|
||||
|
||||
## Ask a staff member in [#support](https://discord.gg/WvfVZ8T)
|
||||
The team is ready to tell you the secrets of the underworld.<br>
|
||||
Join our [Discord server](https://discord.gg/WvfVZ8T) and find out what we're hiding.
|
||||
BIN
.github/TwitterButton.png
vendored
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
42
.github/deploy.ts
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
import * as Client from "ssh2-sftp-client";
|
||||
import * as archiver from "archiver";
|
||||
import * as rimraf from "rimraf";
|
||||
import { platform } from "os";
|
||||
import { createWriteStream } from "fs";
|
||||
|
||||
let sftp = new Client();
|
||||
|
||||
sftp
|
||||
.connect({
|
||||
host: process.env.SSH_HOST,
|
||||
username: process.env.SSH_USERNAME,
|
||||
password: process.env.SSH_PASSWORD
|
||||
})
|
||||
.then(async () => {
|
||||
rimraf.sync("../dist/app/");
|
||||
|
||||
console.log("Zipping...");
|
||||
let output = createWriteStream("app.zip"),
|
||||
archive = archiver("zip");
|
||||
|
||||
archive.directory(`../dist/`, platform());
|
||||
|
||||
output.on("close", function() {
|
||||
console.log("Uploading...");
|
||||
sftp
|
||||
.fastPut("app.zip", `/home/PreMiD/builds/${platform()}.zip`)
|
||||
.then(() => {
|
||||
console.log("Done!");
|
||||
sftp.end();
|
||||
});
|
||||
});
|
||||
|
||||
archive.on("error", function(err) {
|
||||
sftp.end();
|
||||
throw err;
|
||||
});
|
||||
|
||||
archive.pipe(output);
|
||||
|
||||
archive.finalize();
|
||||
});
|
||||
BIN
.github/example.png
vendored
Normal file
|
After Width: | Height: | Size: 332 KiB |
99
.github/workflows/deploy.yml
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
name: DePloY
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".github/**/*"
|
||||
- "src/**/*"
|
||||
- "**.ts"
|
||||
- "package.json"
|
||||
env:
|
||||
NODE_ENV: DePloY
|
||||
jobs:
|
||||
package:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macOS-latest, windows-latest, ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/setup-node@master
|
||||
- name: Install Dependencies
|
||||
run: npm i
|
||||
- name: Prepare to package
|
||||
run: npm run init
|
||||
- name: Package
|
||||
run: |
|
||||
npm run pkg
|
||||
rm -r dist/app
|
||||
node util/zip dist ${{ matrix.os }}.zip --zip
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: ${{ matrix.os }}
|
||||
path: ${{ matrix.os }}.zip
|
||||
installer:
|
||||
needs: package
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/setup-node@master
|
||||
- uses: actions/download-artifact@master
|
||||
with:
|
||||
name: macOS-latest
|
||||
- uses: actions/download-artifact@master
|
||||
with:
|
||||
name: windows-latest
|
||||
- name: Unzip MacOS
|
||||
run: |
|
||||
mkdir dist/
|
||||
unzip macOS-latest/macOS-latest.zip
|
||||
mv macOS-latest/* dist/
|
||||
ls -ls dist/
|
||||
- name: Unzip Windows
|
||||
run: |
|
||||
unzip windows-latest/windows-latest.zip
|
||||
mv windows-latest/** dist/
|
||||
- name: Download InstallBuilder
|
||||
run: |
|
||||
wget https://clients.bitrock.com/installbuilder/installbuilder-enterprise-19.10.0-linux-x64-installer.run
|
||||
chmod u+x installbuilder-enterprise-19.10.0-linux-x64-installer.run
|
||||
- name: Install InstallBuilder
|
||||
run: |
|
||||
./installbuilder-enterprise-19.10.0-linux-x64-installer.run --installer-language en --prefix ./installbuilder --mode unattended
|
||||
echo "${{ secrets.IBLICENSE }}" > ./installbuilder/license.xml
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
npm i -D
|
||||
tsc util/prepare
|
||||
- name: Create Updaters
|
||||
run: |
|
||||
installbuilder/autoupdate/bin/customize.run build installer_assets/updater.xml osx
|
||||
installbuilder/autoupdate/bin/customize.run build installer_assets/updater.xml windows
|
||||
- name: Create installer (MacOS 64bit)
|
||||
run: |
|
||||
node util/prepare PreMiD-darwin-x64
|
||||
installbuilder/bin/builder build installer.xml osx
|
||||
zip -r PreMiD-darwin-x64.zip dist/installer
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: PreMiD-darwin-x64
|
||||
path: PreMiD-darwin-x64.zip
|
||||
- name: Create installer (Windows 64bit)
|
||||
run: |
|
||||
rm -r dist/installer/*
|
||||
node util/prepare PreMiD-win32-x64
|
||||
installbuilder/bin/builder build installer.xml windows
|
||||
zip -r PreMiD-win32-x64.zip dist/installer
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: PreMiD-win32-x64
|
||||
path: PreMiD-win32-x64.zip
|
||||
- name: Create installer (Windows 32bit)
|
||||
run: |
|
||||
rm -r dist/installer/*
|
||||
node util/prepare PreMiD-win32-ia32
|
||||
installbuilder/bin/builder build installer.xml windows
|
||||
zip -r PreMiD-win32-ia32.zip dist/installer
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: PreMiD-win32-ia32
|
||||
path: PreMiD-win32-ia32.zip
|
||||
16
.gitignore
vendored
@@ -1,6 +1,16 @@
|
||||
node_modules
|
||||
out
|
||||
dist
|
||||
website
|
||||
server
|
||||
.vscode
|
||||
tmp
|
||||
|
||||
.vscode
|
||||
.env
|
||||
|
||||
src/package-lock.json
|
||||
src/package.json
|
||||
src/update.ini
|
||||
|
||||
*.exe
|
||||
*.app
|
||||
*.xml.backup
|
||||
*.js
|
||||
22
@types/PreMiD/ExtensionSettings.d.ts
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
export default interface ExtensionSettings {
|
||||
/**
|
||||
* If extension is enabled
|
||||
*/
|
||||
enabled: boolean;
|
||||
/**
|
||||
* Autolaunch enabled
|
||||
*/
|
||||
autoLaunch: boolean;
|
||||
/**
|
||||
* Media keys enabled
|
||||
*/
|
||||
mediaKeys: boolean;
|
||||
/**
|
||||
* title menubar (TrayTitle)
|
||||
*/
|
||||
titleMenubar: boolean;
|
||||
/**
|
||||
* language of extension
|
||||
*/
|
||||
language: string;
|
||||
}
|
||||
16
@types/PreMiD/Presence.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import * as Discord from "discord-rpc";
|
||||
|
||||
export default interface Presence {
|
||||
/**
|
||||
* Client ID of presence
|
||||
*/
|
||||
clientId: string;
|
||||
/**
|
||||
* Rich Procedual call connection
|
||||
*/
|
||||
rpc: Discord.Client;
|
||||
/**
|
||||
* Connection ready?
|
||||
*/
|
||||
ready: Boolean;
|
||||
}
|
||||
33
@types/PreMiD/PresenceData.d.ts
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import * as Discord from "discord-rpc";
|
||||
|
||||
export default interface PresenceData {
|
||||
/**
|
||||
* Client ID of presence
|
||||
*/
|
||||
clientId: string;
|
||||
/**
|
||||
* Tray title to be shown in Mac OS tray
|
||||
*/
|
||||
trayTitle: string;
|
||||
/**
|
||||
* service name of presence
|
||||
* @deprecated
|
||||
*/
|
||||
service: string;
|
||||
/**
|
||||
* Determines if the service is currently playing something back or not, if false it will automatically hide after 1 minute
|
||||
*/
|
||||
playback: boolean;
|
||||
/**
|
||||
* Discord Presence which gets sent directly to Discord app
|
||||
*/
|
||||
presenceData: Discord.Presence;
|
||||
/**
|
||||
* Determines if the service should be hidden (clearActivity)
|
||||
*/
|
||||
hidden: boolean;
|
||||
/**
|
||||
* Determines if the service is mediaKey able / uses them
|
||||
*/
|
||||
mediaKeys: boolean;
|
||||
}
|
||||
66
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at contact@premid.app or by contacting a staff member on our [Discord server](https://discord.gg/WvfVZ8T). All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
@@ -1,104 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
{
|
||||
"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,54 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/* 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%;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#content h1 {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
tr td:first-child {
|
||||
width: 90%;
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
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,137 +0,0 @@
|
||||
<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>
|
||||
@@ -1,28 +0,0 @@
|
||||
<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>
|
||||
@@ -1,36 +0,0 @@
|
||||
<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>
|
||||
@@ -1,32 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 18 KiB |
@@ -1 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
@@ -1,62 +0,0 @@
|
||||
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)
|
||||
@@ -1,11 +0,0 @@
|
||||
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")
|
||||
@@ -1,140 +0,0 @@
|
||||
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})
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
$(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)
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
|
||||
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
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
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")
|
||||
2
Extension/js/util/jquery-3.3.1.min.js
vendored
7
Extension/js/util/socket.io-2.1.1.min.js
vendored
@@ -1,27 +0,0 @@
|
||||
//* 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,75 +0,0 @@
|
||||
{
|
||||
"name": "PreMiD",
|
||||
"author": "Timeraa",
|
||||
"version": "1.2",
|
||||
"description": "__MSG_appDesc__",
|
||||
"manifest_version": 2,
|
||||
"default_locale": "en",
|
||||
"icons": {
|
||||
"2024": "icon.png"
|
||||
},
|
||||
"background": {
|
||||
"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": "icon.png"
|
||||
}
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"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": ["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:3020/",
|
||||
"tabs",
|
||||
"storage",
|
||||
"declarativeContent"
|
||||
]
|
||||
}
|
||||
386
LICENSE
@@ -1,21 +1,373 @@
|
||||
MIT License
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
Copyright (c) 2018 Florian Metz
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
|
||||
203
README.md
@@ -1,182 +1,43 @@
|
||||
##  [](https://discord.gg/Kw7WaYn)
|
||||
<div align="center">
|
||||
|
||||
# <img src="gitassets/premid.webp" width="24px" draggable="false"><b> </b>PreMiD · Discord Rich Presence for your Media!
|
||||
<img src=".github/Logo.png" width="150px" draggable="false"><br>
|
||||
|
||||
<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>
|
||||
# PreMiD
|
||||
|
||||
## Your Rich Presence for web services!
|
||||
|
||||

|
||||

|
||||

|
||||
[](https://chrome.google.com/webstore/detail/premid/agjnjboanicjcpenljmaaigopkgdnihi)
|
||||

|
||||

|
||||

|
||||
|
||||
<img src=".github/example.png" draggable="false"><br>
|
||||
|
||||
# About
|
||||
|
||||
## Summary
|
||||
**PreMiD** is a simple, configurable utility that allows you to show what you're doing on the web in your Discord **now playing status**. It supports many different websites, and will support multiple users watching the same content simultaneously in an upcoming update.
|
||||
|
||||
**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
|
||||
|
||||
## Features
|
||||
· Displays your current web service in Discord as your status.<br>
|
||||
· Grants full control over Presences.<br>
|
||||
· Supports over 100 web services, still rising!<br>
|
||||
· _Watch parties and more are coming soon!_
|
||||
|
||||
- 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!_
|
||||
# Installation/Troubleshooting
|
||||
|
||||
# Table of contents
|
||||
### Installation instructions, Troubleshooting guides etc. can be found in our [**Wiki**](https://wiki.premid.app).
|
||||
|
||||
- [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 us
|
||||
|
||||
# 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>
|
||||
<ol>
|
||||
<li>Click <a href="https://chrome.google.com/webstore/detail/yt-presence/agjnjboanicjcpenljmaaigopkgdnihi">this</a> link</li>
|
||||
</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>
|
||||
<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 Folder <b>"Extension"</b> on the page<br>
|
||||
<li>Install the <a href="#application">application</a></li>
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
## Application
|
||||
|
||||
<details>
|
||||
<summary><b><u>Mac OS</u></b> (Click to expand)</summary>
|
||||
<h1>Installation on Mac OS</h1>
|
||||
<ol>
|
||||
<li>Download the latest version of the <a href="https://github.com/Timeraa/YT-Presence/releases/latest">application</a>
|
||||
</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>
|
||||
|
||||
<details>
|
||||
<summary><b><u>Windows</u></b> (Click to expand)</summary>
|
||||
<h1>Installation on Windows</h1>
|
||||
<ol>
|
||||
<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>
|
||||
|
||||
---
|
||||
|
||||
<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!
|
||||
<div>
|
||||
<a target="_blank" href="https://www.patreon.com/bePatron?u=4610890" data-patreon-widget-type="become-patron-button" title="Support me on Patreon!">
|
||||
<img height="75px" draggable="false" src=".github/Patreon.png">
|
||||
</a>
|
||||
<a target="_blank" href="https://discord.gg/WvfVZ8T" title="Join our Discord!">
|
||||
<img height="75px" draggable="false" src="https://discordapp.com/api/guilds/493130730549805057/widget.png?style=banner2" alt="Join my Discord!">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
BIN
appIcon.icns
BIN
appIcon.ico
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 79 KiB |
@@ -1,55 +0,0 @@
|
||||
<?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>
|
||||
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 129 KiB |
@@ -1 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 540 KiB |
|
Before Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 500 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 1.9 MiB |
39
installer.js
@@ -1,39 +0,0 @@
|
||||
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}`));
|
||||
}
|
||||
BIN
installer_assets/appIcon.icns
Normal file
BIN
installer_assets/appIcon.ico
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
installer_assets/appIcon.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
257
installer_assets/installer.xml
Normal file
@@ -0,0 +1,257 @@
|
||||
<project>
|
||||
<shortName>PreMiD</shortName>
|
||||
<fullName>PreMiD</fullName>
|
||||
<version>VERSION</version>
|
||||
<installerFilename>${product_fullname}-${product_version}-installer_64bit.${platform_exec_suffix}</installerFilename>
|
||||
<wrapLicenseFileText>0</wrapLicenseFileText>
|
||||
<logoImage>../installer_assets/appIcon.png</logoImage>
|
||||
<osxApplicationBundleIcon>../installer_assets/appIcon.icns</osxApplicationBundleIcon>
|
||||
<componentList>
|
||||
<component>
|
||||
<name>default</name>
|
||||
<description>Default Component</description>
|
||||
<canBeEdited>1</canBeEdited>
|
||||
<selected>1</selected>
|
||||
<show>1</show>
|
||||
<folderList>
|
||||
<folder>
|
||||
<description>Program Files</description>
|
||||
<destination>${installdir}</destination>
|
||||
<name>programfiles</name>
|
||||
<platforms>all</platforms>
|
||||
<distributionFileList>
|
||||
<distributionFile>
|
||||
<origin>update.ini</origin>
|
||||
</distributionFile>
|
||||
</distributionFileList>
|
||||
</folder>
|
||||
<folder>
|
||||
<description>Program Files</description>
|
||||
<destination>${installdir}</destination>
|
||||
<name>programfileslinux</name>
|
||||
<platforms>linux</platforms>
|
||||
</folder>
|
||||
<folder>
|
||||
<description>Program Files</description>
|
||||
<destination>${installdir}</destination>
|
||||
<name>programfileswindows</name>
|
||||
<platforms>windows</platforms>
|
||||
<distributionFileList>
|
||||
<distributionDirectory allowWildcards="1">
|
||||
<origin>../dist/PACKAGEDNAME/*</origin>
|
||||
</distributionDirectory>
|
||||
<distributionFile>
|
||||
<origin>../installer_assets/appIcon.ico</origin>
|
||||
</distributionFile>
|
||||
<distributionFile>
|
||||
<origin>../installer_assets/updater.exe</origin>
|
||||
</distributionFile>
|
||||
</distributionFileList>
|
||||
</folder>
|
||||
<folder>
|
||||
<description>Program Files</description>
|
||||
<destination>${installdir}</destination>
|
||||
<name>programfilesosx</name>
|
||||
<platforms>osx</platforms>
|
||||
<distributionFileList>
|
||||
<distributionFile>
|
||||
<origin>../installer_assets/updater.app</origin>
|
||||
</distributionFile>
|
||||
<distributionFile>
|
||||
<origin>../dist/PACKAGEDNAME/PreMiD.app</origin>
|
||||
</distributionFile>
|
||||
</distributionFileList>
|
||||
</folder>
|
||||
</folderList>
|
||||
<startMenuShortcutList>
|
||||
<startMenuShortcut>
|
||||
<comment></comment>
|
||||
<name>${product_fullname}</name>
|
||||
<runAsAdmin>0</runAsAdmin>
|
||||
<runInTerminal>0</runInTerminal>
|
||||
<windowsExec>${installdir}/PreMiD.exe</windowsExec>
|
||||
<windowsExecArgs></windowsExecArgs>
|
||||
<windowsIcon></windowsIcon>
|
||||
<windowsPath>${installdir}/</windowsPath>
|
||||
</startMenuShortcut>
|
||||
</startMenuShortcutList>
|
||||
</component>
|
||||
</componentList>
|
||||
<preInstallationActionList>
|
||||
<kill>
|
||||
<abortOnError>0</abortOnError>
|
||||
<name>${product_fullname}.exe</name>
|
||||
<progressText>Killing ${product_fullname}</progressText>
|
||||
<showMessageOnError>0</showMessageOnError>
|
||||
<ruleList>
|
||||
<platformTest>
|
||||
<type>windows</type>
|
||||
</platformTest>
|
||||
</ruleList>
|
||||
</kill>
|
||||
<runProgram>
|
||||
<program>pkill</program>
|
||||
<programArguments>PreMiD</programArguments>
|
||||
<runAs>${env(USER)}</runAs>
|
||||
<useMSDOSPath>0</useMSDOSPath>
|
||||
<workingDirectory>${installdir}/</workingDirectory>
|
||||
<ruleList>
|
||||
<platformTest>
|
||||
<type>osx</type>
|
||||
</platformTest>
|
||||
<processTest>
|
||||
<logic>is_running</logic>
|
||||
<name>PreMiD</name>
|
||||
</processTest>
|
||||
</ruleList>
|
||||
</runProgram>
|
||||
<runProgram>
|
||||
<program>${windows_folder_local_appdata}\premid\Update.exe</program>
|
||||
<programArguments>--uninstall</programArguments>
|
||||
<onErrorActionList>
|
||||
<deleteFile>
|
||||
<matchHiddenFiles>1</matchHiddenFiles>
|
||||
<path>${windows_folder_local_appdata}\premid</path>
|
||||
</deleteFile>
|
||||
</onErrorActionList>
|
||||
<ruleList>
|
||||
<platformTest>
|
||||
<type>windows</type>
|
||||
</platformTest>
|
||||
<fileExists>
|
||||
<path>${windows_folder_local_appdata}\premid\PreMiD.exe</path>
|
||||
</fileExists>
|
||||
</ruleList>
|
||||
</runProgram>
|
||||
<runProgram>
|
||||
<program>${windows_folder_common_appdata}\${system_username}\premid\Update.exe</program>
|
||||
<programArguments>--uninstall</programArguments>
|
||||
<onErrorActionList>
|
||||
<deleteFile>
|
||||
<matchHiddenFiles>1</matchHiddenFiles>
|
||||
<path>${windows_folder_common_appdata}\${system_username}\premid</path>
|
||||
</deleteFile>
|
||||
</onErrorActionList>
|
||||
<ruleList>
|
||||
<platformTest>
|
||||
<type>windows</type>
|
||||
</platformTest>
|
||||
<fileExists>
|
||||
<path>${windows_folder_common_appdata}\${system_username}\premid\PreMiD.exe</path>
|
||||
</fileExists>
|
||||
</ruleList>
|
||||
</runProgram>
|
||||
</preInstallationActionList>
|
||||
<postInstallationActionList>
|
||||
<runProgram>
|
||||
<abortOnError>0</abortOnError>
|
||||
<program>PreMiD.exe</program>
|
||||
<programArguments>&</programArguments>
|
||||
<progressText>Launching PreMiD</progressText>
|
||||
<show>0</show>
|
||||
<showMessageOnError>0</showMessageOnError>
|
||||
<workingDirectory>${installdir}</workingDirectory>
|
||||
<ruleList>
|
||||
<platformTest>
|
||||
<type>windows</type>
|
||||
</platformTest>
|
||||
</ruleList>
|
||||
</runProgram>
|
||||
<setInstallerVariableFromRegEx show="0">
|
||||
<name>escaped_installdir</name>
|
||||
<pattern> </pattern>
|
||||
<substitution>\\ </substitution>
|
||||
<text>${installdir}</text>
|
||||
</setInstallerVariableFromRegEx>
|
||||
<runProgram>
|
||||
<program>open</program>
|
||||
<programArguments> ${escaped_installdir}/PreMiD.app</programArguments>
|
||||
<progressText>Launching PreMiD</progressText>
|
||||
<runAs>${env(USER)}</runAs>
|
||||
<useMSDOSPath>0</useMSDOSPath>
|
||||
<workingDirectory>${installdir}/</workingDirectory>
|
||||
<ruleList>
|
||||
<platformTest>
|
||||
<type>osx</type>
|
||||
</platformTest>
|
||||
</ruleList>
|
||||
</runProgram>
|
||||
<deleteFile>
|
||||
<path>${installdir}/update</path>
|
||||
</deleteFile>
|
||||
<addDirectoriesToUninstaller>
|
||||
<addContents>1</addContents>
|
||||
<files>${installdir}</files>
|
||||
</addDirectoriesToUninstaller>
|
||||
<deleteFile>
|
||||
<path>${windows_folder_local_appdata}\premid</path>
|
||||
<ruleList>
|
||||
<platformTest>
|
||||
<type>windows</type>
|
||||
</platformTest>
|
||||
</ruleList>
|
||||
</deleteFile>
|
||||
</postInstallationActionList>
|
||||
<preUninstallationActionList>
|
||||
<kill>
|
||||
<abortOnError>0</abortOnError>
|
||||
<name>${product_fullname}.exe</name>
|
||||
<progressText>Killing ${product_fullname}</progressText>
|
||||
<showMessageOnError>0</showMessageOnError>
|
||||
<ruleList>
|
||||
<platformTest>
|
||||
<type>windows</type>
|
||||
</platformTest>
|
||||
</ruleList>
|
||||
</kill>
|
||||
<runProgram>
|
||||
<program>pkill</program>
|
||||
<programArguments>PreMiD</programArguments>
|
||||
<runAs>${env(USER)}</runAs>
|
||||
<useMSDOSPath>0</useMSDOSPath>
|
||||
<workingDirectory>${installdir}/</workingDirectory>
|
||||
<ruleList>
|
||||
<platformTest>
|
||||
<type>osx</type>
|
||||
</platformTest>
|
||||
<processTest>
|
||||
<logic>is_running</logic>
|
||||
<name>PreMiD</name>
|
||||
</processTest>
|
||||
</ruleList>
|
||||
</runProgram>
|
||||
<deleteFile>
|
||||
<path>${installdir}/update/</path>
|
||||
</deleteFile>
|
||||
<deleteFile>
|
||||
<matchHiddenFiles>1</matchHiddenFiles>
|
||||
<path>${windows_folder_appdata}/${product_fullname}</path>
|
||||
</deleteFile>
|
||||
</preUninstallationActionList>
|
||||
<defaultInstallationMode>unattended</defaultInstallationMode>
|
||||
<enableRollback>0</enableRollback>
|
||||
<enableTimestamp>1</enableTimestamp>
|
||||
<installationScope>user</installationScope>
|
||||
<overwritePolicy>onlyIfNewer</overwritePolicy>
|
||||
<osxApplicationBundleIdentifier>eu.Timeraa.PreMiD</osxApplicationBundleIdentifier>
|
||||
<outputDirectory>../dist/installer</outputDirectory>
|
||||
<productDisplayIcon>${installdir}/appIcon.ico</productDisplayIcon>
|
||||
<saveRelativePaths>1</saveRelativePaths>
|
||||
<unattendedModeUI>minimal</unattendedModeUI>
|
||||
<vendor>Timeraa</vendor>
|
||||
<windowsExecutableIcon>../installer_assets/appIcon.ico</windowsExecutableIcon>
|
||||
<parameterList>
|
||||
<directoryParameter>
|
||||
<name>installdir</name>
|
||||
<description>Installer.Parameter.installdir.description</description>
|
||||
<explanation>Installer.Parameter.installdir.explanation</explanation>
|
||||
<value></value>
|
||||
<default>${platform_install_prefix}/${product_shortname}</default>
|
||||
<allowEmptyValue>0</allowEmptyValue>
|
||||
<cliOptionName>prefix</cliOptionName>
|
||||
<mustBeWritable>1</mustBeWritable>
|
||||
<mustExist>0</mustExist>
|
||||
<width>40</width>
|
||||
</directoryParameter>
|
||||
</parameterList>
|
||||
</project>
|
||||
6
installer_assets/update.ini
Normal file
@@ -0,0 +1,6 @@
|
||||
[Update]
|
||||
|
||||
url=https://api.premid.app/app/update/64bit/
|
||||
version_id= ?
|
||||
check_for_updates=1
|
||||
update_download_location=${installer_directory}/update
|
||||
11
installer_assets/updater.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<autoUpdateProject>
|
||||
<fullName>PreMiD</fullName>
|
||||
<shortName>PreMiD</shortName>
|
||||
<vendor>Timeraa</vendor>
|
||||
<version>2.0</version>
|
||||
<singleInstanceCheck>1</singleInstanceCheck>
|
||||
<requestedExecutionLevel>asInvoker</requestedExecutionLevel>
|
||||
<enableSslSupport>1</enableSslSupport>
|
||||
<outputDirectory>./</outputDirectory>
|
||||
<installerFilename>updater.${platform_exec_suffix}</installerFilename>
|
||||
</autoUpdateProject>
|
||||
2999
package-lock.json
generated
61
package.json
@@ -1,25 +1,54 @@
|
||||
{
|
||||
"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",
|
||||
"description": "Discord Rich Presence for websites.",
|
||||
"version": "2.0.5",
|
||||
"repository": "https://github.com/PreMiD/PreMiD",
|
||||
"scripts": {
|
||||
"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"
|
||||
"init": "tsc && tsc pkg util/prepare util/zip && devScript --copyOnly",
|
||||
"start": "electron dist/app/.",
|
||||
"dev": "devScript",
|
||||
"pkg": "rimraf dist && tsc && devScript --copyOnly && cd dist/app/ && yarn && cd ../../ && node pkg",
|
||||
"deploy": "tsc .github/deploy && cd .github && node deploy.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Timeraa",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"chalk": "^2.4.1",
|
||||
"electron-installer-dmg": "^1.0.0",
|
||||
"electron-installer-windows": "^1.1.0",
|
||||
"electron-packager": "^12.2.0",
|
||||
"electron-winstaller": "^2.7.0"
|
||||
"@timeraa/devscript": "Timeraa/DevScript",
|
||||
"@types/archiver": "3.0.0",
|
||||
"@types/auto-launch": "5.0.1",
|
||||
"@types/discord-rpc": "3.0.2",
|
||||
"@types/electron-packager": "14.0.0",
|
||||
"@types/fs-extra": "8.0.1",
|
||||
"@types/ini": "1.3.30",
|
||||
"@types/node": "^12.12.14",
|
||||
"@types/prompts": "2.0.3",
|
||||
"@types/request-promise-native": "1.0.17",
|
||||
"@types/rimraf": "2.0.3",
|
||||
"@types/socket.io": "2.1.4",
|
||||
"@types/ssh2-sftp-client": "4.1.1",
|
||||
"@types/unzipper": "^0.10.1",
|
||||
"archiver": "3.1.1",
|
||||
"chalk": "3.0.0",
|
||||
"electron": "7.1.2",
|
||||
"electron-packager": "14.1.1",
|
||||
"fast-glob": "3.1.0",
|
||||
"fs-extra": "8.1.0",
|
||||
"ini": "1.3.5",
|
||||
"nodemon": "2.0.1",
|
||||
"ora": "4.0.3",
|
||||
"prompts": "2.3.0",
|
||||
"rimraf": "3.0.0",
|
||||
"source-map-support": "0.5.16",
|
||||
"ssh2-sftp-client": "4.2.4",
|
||||
"typescript": "3.7.2",
|
||||
"unzipper": "^0.10.5",
|
||||
"yarn": "^1.19.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"auto-launch": "5.0.5",
|
||||
"discord-rpc": "github:discordjs/RPC",
|
||||
"electron-store": "5.1.0",
|
||||
"socket.io": "2.3.0",
|
||||
"sudo-prompt": "9.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
233
pkg.ts
Normal file
@@ -0,0 +1,233 @@
|
||||
import * as electronPackager from "electron-packager";
|
||||
import { platform, arch } from "os";
|
||||
import { existsSync, readFileSync, writeFileSync } from "fs";
|
||||
import { resolve } from "path";
|
||||
import { exec } from "child_process";
|
||||
import { removeSync, ensureDirSync } from "fs-extra";
|
||||
import { parse, stringify } from "ini";
|
||||
import * as prompts from "prompts";
|
||||
import * as ora from "ora";
|
||||
|
||||
(async () => {
|
||||
let response = {
|
||||
os: "current",
|
||||
arch: "all",
|
||||
installer: false
|
||||
};
|
||||
|
||||
if (process.env.NODE_ENV !== "DePloY")
|
||||
response = await prompts([
|
||||
{
|
||||
type: "select",
|
||||
name: "arch",
|
||||
message: "What architecture?",
|
||||
choices: [
|
||||
{
|
||||
title: "current",
|
||||
value: "current"
|
||||
},
|
||||
{
|
||||
title: "all",
|
||||
value: "all"
|
||||
},
|
||||
{
|
||||
title: "arm64",
|
||||
value: "arm64"
|
||||
},
|
||||
{
|
||||
title: "armv7l",
|
||||
value: "armv7l"
|
||||
},
|
||||
{
|
||||
title: "ia32",
|
||||
value: "ia32"
|
||||
},
|
||||
{
|
||||
title: "mips64el",
|
||||
value: "mips64el"
|
||||
},
|
||||
{
|
||||
title: "x64",
|
||||
value: "x64"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "select",
|
||||
name: "os",
|
||||
message: "What operating system?",
|
||||
choices: [
|
||||
{
|
||||
title: "current",
|
||||
value: "current"
|
||||
},
|
||||
{
|
||||
title: "all",
|
||||
value: "all"
|
||||
},
|
||||
{
|
||||
title: "darwin",
|
||||
value: "darwin"
|
||||
},
|
||||
{
|
||||
title: "linux",
|
||||
value: "linux"
|
||||
},
|
||||
{
|
||||
title: "mas",
|
||||
value: "mas"
|
||||
},
|
||||
{
|
||||
title: "win32",
|
||||
value: "win32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "confirm",
|
||||
name: "installer",
|
||||
message: "With installer?"
|
||||
}
|
||||
]);
|
||||
|
||||
//#region WIP
|
||||
let installerXml = readFileSync(`installer_assets/installer.xml`, "utf-8");
|
||||
|
||||
installerXml = installerXml.replace(
|
||||
"{{VERSION}}",
|
||||
require("./package.json").version
|
||||
);
|
||||
installerXml = installerXml.replace(
|
||||
/(PACKAGEDNAME)/g,
|
||||
`PreMiD-${platform()}-${arch()}`
|
||||
);
|
||||
|
||||
ensureDirSync("tmp");
|
||||
writeFileSync("tmp/installer.xml", installerXml);
|
||||
//#endregion
|
||||
|
||||
if (!response.os) {
|
||||
process.exit();
|
||||
return;
|
||||
}
|
||||
|
||||
let icon: string;
|
||||
|
||||
if (
|
||||
response.os == "darwin" ||
|
||||
(response.os === "current" && platform() === "darwin")
|
||||
)
|
||||
icon = "./installer_assets/appIcon.icns";
|
||||
if (["ia32", "x64"].includes(response.arch) || platform() === "win32")
|
||||
icon = "./installer_assets/appIcon.ico";
|
||||
|
||||
if (existsSync("./dist/app/update.ini")) removeSync("./dist/app/update.ini");
|
||||
if (existsSync("./dist/app/updater.app"))
|
||||
removeSync("./dist/app/updater.app");
|
||||
if (existsSync("./dist/app/updater.exe"))
|
||||
removeSync("./dist/app/updater.exe");
|
||||
|
||||
let spinner = ora("Packaging app").start(),
|
||||
packagingOptions: electronPackager.Options = {
|
||||
dir: "./dist/app",
|
||||
out: "./dist",
|
||||
darwinDarkModeSupport: true,
|
||||
icon: icon,
|
||||
overwrite: true,
|
||||
quiet: true,
|
||||
appBundleId: "eu.Timeraa.PreMiD",
|
||||
appCategoryType: "Utilities",
|
||||
appCopyright: `Timeraa 2018-${new Date().getFullYear()}`,
|
||||
prune: true,
|
||||
// @ts-ignore
|
||||
arch: response.arch,
|
||||
// @ts-ignore
|
||||
platform: response.os
|
||||
};
|
||||
|
||||
if (response.arch === "current") delete packagingOptions.arch;
|
||||
if (response.os === "current") delete packagingOptions.platform;
|
||||
|
||||
// @ts-ignore
|
||||
electronPackager(packagingOptions).then(() => {
|
||||
if (!response.installer) {
|
||||
spinner.text = "Done!";
|
||||
spinner.succeed();
|
||||
process.exit();
|
||||
return;
|
||||
}
|
||||
|
||||
let versionId = "0" + require("./package.json").version.replace(/[.]/g, ""),
|
||||
updateIni = parse(readFileSync("./installer_assets/update.ini", "utf-8"));
|
||||
|
||||
updateIni.Update.version_id = versionId;
|
||||
|
||||
ensureDirSync("./tmp");
|
||||
writeFileSync("./tmp/update.ini", stringify(updateIni));
|
||||
|
||||
let bitRockBuilder = "",
|
||||
bitRockUpdater = "";
|
||||
|
||||
if (platform() === "win32") {
|
||||
bitRockBuilder = resolve(
|
||||
"C:/Program Files (x86)/BitRock InstallBuilder Enterprise 19.8.0/bin/builder-cli.exe"
|
||||
);
|
||||
bitRockUpdater = resolve(
|
||||
"C:/Program Files (x86)/BitRock InstallBuilder Enterprise 19.8.0/autoupdate/bin/customize.exe"
|
||||
);
|
||||
}
|
||||
|
||||
if (platform() === "darwin") {
|
||||
bitRockBuilder = resolve(
|
||||
"/Applications/Installbuilder/bin/Builder.app/Contents/MacOS/installbuilder.sh"
|
||||
);
|
||||
bitRockUpdater = resolve(
|
||||
"/Applications/Installbuilder/autoupdate/bin/customize.sh"
|
||||
);
|
||||
}
|
||||
|
||||
if (!existsSync(bitRockBuilder) || !existsSync(bitRockUpdater)) {
|
||||
spinner.fail("Bitrock installation not found.");
|
||||
process.exit();
|
||||
return;
|
||||
}
|
||||
|
||||
spinner.text = "Building updater";
|
||||
|
||||
let updater = exec(
|
||||
`"${bitRockUpdater}" build installer_assets/updater.xml ${
|
||||
platform() === "win32" ? "windows" : "osx"
|
||||
}`
|
||||
);
|
||||
|
||||
updater.once("exit", (code, signal) => {
|
||||
if (![0, 1].includes(code)) {
|
||||
spinner.fail(`Updater failed with code ${code}: ${signal}`);
|
||||
process.exit();
|
||||
return;
|
||||
}
|
||||
|
||||
spinner.text = "Building installer";
|
||||
let builder = exec(
|
||||
`"${bitRockBuilder}" build tmp/installer.xml ${
|
||||
platform() === "win32" ? "windows" : "osx"
|
||||
}`
|
||||
);
|
||||
|
||||
builder.once("exit", code => {
|
||||
removeSync("./tmp");
|
||||
|
||||
if (code !== 0) {
|
||||
spinner.fail(`Error code: ${code}`);
|
||||
process.exit();
|
||||
return;
|
||||
}
|
||||
|
||||
spinner.text = "Done!";
|
||||
spinner.succeed();
|
||||
process.exit();
|
||||
return;
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
BIN
src/assets/appIcon.icns
Normal file
|
Before Width: | Height: | Size: 885 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 18 KiB |
BIN
src/assets/tray/Icon@2x.png
Normal file
|
After Width: | Height: | Size: 986 B |
BIN
src/assets/tray/Icon@2xTemplate.png
Normal file
|
After Width: | Height: | Size: 986 B |
BIN
src/assets/tray/IconTemplate.png
Normal file
|
After Width: | Height: | Size: 880 B |
BIN
src/assets/tray/icon.png
Normal file
|
After Width: | Height: | Size: 880 B |
91
src/index.js
@@ -1,91 +0,0 @@
|
||||
//* Handle Winstall
|
||||
require('./util/handleWinstall')
|
||||
|
||||
//#region Define constants
|
||||
//* Declare needed constants
|
||||
const {app} = require('electron')
|
||||
|
||||
//* Require config
|
||||
var pjson = require('./package.json');
|
||||
//* Require electron-config
|
||||
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
|
||||
|
||||
//* Set app user model id
|
||||
app.setAppUserModelId("eu.Timeraa.premid")
|
||||
|
||||
//* Define Global Variables
|
||||
global.PLATFORM = os.platform()
|
||||
global.UPDATEAVAIABLE = ""
|
||||
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')(": ")
|
||||
|
||||
|
||||
//* Clear console
|
||||
process.stdout.write("\u001b[2J\u001b[0;0H");
|
||||
|
||||
//* Single Instance Check
|
||||
var iShouldQuit = app.makeSingleInstance(() => {return true});
|
||||
|
||||
if(iShouldQuit){
|
||||
console.log(CONSOLEPREFIX + chalk.red("App already running, closing current instance..."))
|
||||
app.quit();
|
||||
return;
|
||||
}
|
||||
|
||||
//* Set default values for electon-config userSettings
|
||||
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(PLATFORM == "darwin") {
|
||||
app.dock.setBadge("V" + VERSION)
|
||||
}
|
||||
|
||||
console.log(CONSOLEPREFIX + chalk.yellow("Loading..."))
|
||||
|
||||
//* App ready
|
||||
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
|
||||
app.on('ready', appReady);
|
||||
|
||||
//* Prevent default behaviour
|
||||
app.on('window-all-closed', () => {});
|
||||
45
src/index.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { app, dialog } from "electron";
|
||||
//* Source .map support if devEnv
|
||||
if (!app.isPackaged) require("source-map-support").install();
|
||||
|
||||
import { init as initSocket, socket } from "./managers/socketManager";
|
||||
import { init as initTray } from "./managers/trayManager";
|
||||
import { update as initAutoLaunch } from "./managers/launchManager";
|
||||
import { platform } from "os";
|
||||
import { checkForUpdate } from "./util/updateChecker";
|
||||
|
||||
//* Define and set it to null
|
||||
//* Set AppUserModelId for task manager etc
|
||||
//* When app is ready
|
||||
export let updateCheckerInterval = null;
|
||||
app.setAppUserModelId("Timeraa.PreMiD");
|
||||
app.whenReady().then(async () => {
|
||||
//* Init auto launch
|
||||
//* Check for updates > Update and relaunch
|
||||
//* Init socket
|
||||
//* init application tray icon
|
||||
//* If app is packaged, run an update check every 15 mins
|
||||
initAutoLaunch();
|
||||
await checkForUpdate(true);
|
||||
await initSocket();
|
||||
await initTray();
|
||||
app.isPackaged
|
||||
? (updateCheckerInterval = setInterval(checkForUpdate, 15 * 1000 * 60))
|
||||
: undefined;
|
||||
if (platform() === "darwin") app.dock.hide();
|
||||
});
|
||||
|
||||
//* If second instance started, close old one
|
||||
app.on("second-instance", app.quit);
|
||||
|
||||
//* Send errors from app to extension
|
||||
process.on("unhandledRejection", rejection => {
|
||||
console.log(rejection);
|
||||
socket.emit("unhandledRejection", rejection);
|
||||
});
|
||||
|
||||
// TODO Find better way to log
|
||||
process.on("uncaughtException", err => {
|
||||
dialog.showErrorBox(err.name, err.stack);
|
||||
app.exit(0);
|
||||
});
|
||||
118
src/managers/discordManager.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import { Client } from "discord-rpc";
|
||||
import { app } from "electron";
|
||||
import { platform } from "os";
|
||||
import { tray } from "./trayManager";
|
||||
import { info } from "../util/debug";
|
||||
|
||||
//* Import custom types
|
||||
import Presence from "../../@types/PreMiD/Presence";
|
||||
import PresenceData from "../../@types/PreMiD/PresenceData";
|
||||
|
||||
//* Define Presence array
|
||||
let loggedInPresences: Array<Presence> = [];
|
||||
|
||||
/**
|
||||
* Sets the user's activity
|
||||
* @param presence PresenceData to set activity
|
||||
*/
|
||||
export function setActivity(presence: PresenceData) {
|
||||
//* If platform is darwin (Mac OS) set trayTitle if theres one
|
||||
//* Check if theres an active RPC connection that we can use
|
||||
//* If we have one, use it
|
||||
//* Else create one and use it
|
||||
//* Show debug
|
||||
if (platform() === "darwin" && presence.trayTitle)
|
||||
tray.setTitle(presence.trayTitle);
|
||||
let rpc = loggedInPresences.find(p => p.clientId === presence.clientId);
|
||||
if (rpc) rpc.rpc.setActivity(presence.presenceData).catch(destroy);
|
||||
else
|
||||
loginPresence(presence.clientId).then(p =>
|
||||
p.rpc.setActivity(presence.presenceData).catch(destroy)
|
||||
);
|
||||
info("setActivity");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a user's activity
|
||||
* @param clientId clientId of presence to clear
|
||||
*/
|
||||
export function clearActivity(clientId: string = undefined) {
|
||||
//* Clear tray title
|
||||
//* If clientId set
|
||||
//* Else map through presences and clear them
|
||||
//* Show Debug
|
||||
if (platform() === "darwin") tray.setTitle("");
|
||||
if (clientId) {
|
||||
//* Check if this presence is logged in
|
||||
//* If it is clear its activity
|
||||
//* Return to prevent further actions
|
||||
let pTC = loggedInPresences.find(p => p.clientId === clientId);
|
||||
if (pTC) pTC.rpc.clearActivity().catch(destroy);
|
||||
return;
|
||||
}
|
||||
loggedInPresences.map(p => p.rpc.clearActivity().catch(destroy));
|
||||
info("clearActivity");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create RPC connection to discord
|
||||
* @param clientId client ID of presence
|
||||
*/
|
||||
function loginPresence(clientId: string) {
|
||||
//* Return promise that will resolve to either Presence or null
|
||||
return new Promise<Presence>((resolve, reject) => {
|
||||
//* Create presence object
|
||||
//* Add presence to object
|
||||
//* Try login with client id
|
||||
//* Once RPC connection is ready
|
||||
//* Destroy all clients when Discord closed (My issue #42)
|
||||
let presence: Presence = {
|
||||
clientId: clientId,
|
||||
rpc: new Client({ transport: "ipc" }),
|
||||
ready: false
|
||||
};
|
||||
loggedInPresences.push(presence);
|
||||
presence.rpc.login({ clientId: clientId }).catch(() => {
|
||||
//* If couldn't log in remove it from loggedInPresences
|
||||
//* Reject promise
|
||||
loggedInPresences = loggedInPresences.filter(
|
||||
p => p.clientId !== presence.clientId
|
||||
);
|
||||
reject();
|
||||
});
|
||||
presence.rpc.once("ready", () => {
|
||||
//* Update status
|
||||
//* Resolve with presence
|
||||
presence.ready = true;
|
||||
resolve(presence);
|
||||
});
|
||||
// @ts-ignore
|
||||
presence.rpc.once("disconnected", destroy);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys all rpc connections
|
||||
*/
|
||||
export function destroy() {
|
||||
//* Clear tray title
|
||||
//* Map through loggedInPresences and destroy their rpcs
|
||||
//* Set loggedInPresences to new Array
|
||||
//* Return the promise
|
||||
if (platform() === "darwin" && typeof tray !== "undefined") tray.setTitle("");
|
||||
let res = Promise.all(
|
||||
loggedInPresences.map((presence: Presence) =>
|
||||
presence.rpc.destroy().catch(() => {})
|
||||
)
|
||||
);
|
||||
loggedInPresences = [];
|
||||
return res;
|
||||
}
|
||||
|
||||
//* if app will quit
|
||||
app.once("will-quit", () => {
|
||||
//* Show debug
|
||||
//* Destroy all connections
|
||||
info("Closing rpc connections");
|
||||
destroy();
|
||||
});
|
||||
29
src/managers/launchManager.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import AutoLaunch from "auto-launch";
|
||||
import { app } from "electron";
|
||||
import { settings } from "./settingsManager";
|
||||
import { info } from "../util/debug";
|
||||
|
||||
//* Create autoLaunch object
|
||||
let autoLaunch = new AutoLaunch({
|
||||
name: app.name,
|
||||
isHidden: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Updates autoLaunch
|
||||
*/
|
||||
export async function update() {
|
||||
//* If app not packaged return
|
||||
//* Either enable/disable autolaunch
|
||||
if (!app.isPackaged) {
|
||||
//* Show debug
|
||||
//* Return
|
||||
info("Skipping autoLaunch.");
|
||||
return;
|
||||
}
|
||||
if (settings.get("autoLaunch", true))
|
||||
//* Enable if not enabled
|
||||
autoLaunch.enable();
|
||||
//* Disable if enabled
|
||||
else autoLaunch.disable();
|
||||
}
|
||||
77
src/managers/presenceDevManager.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { readdirSync, readFileSync, unwatchFile, watchFile } from "fs";
|
||||
import { dialog } from "electron";
|
||||
import { socket } from "./socketManager";
|
||||
import { extname } from "path";
|
||||
import { info } from "../util/debug";
|
||||
|
||||
let presenceDevWatchedFiles = [],
|
||||
currWatchPath = "";
|
||||
|
||||
export async function watchDir(path: string) {
|
||||
//* Read dir
|
||||
//* Set currWatchDir
|
||||
//* Set watched files to files
|
||||
//* Add file watcher to each file
|
||||
let files = await readdirSync(path);
|
||||
currWatchPath = path + "/";
|
||||
presenceDevWatchedFiles = files;
|
||||
presenceDevWatchedFiles.map(f => {
|
||||
//* Watch file
|
||||
//* ReadFiles
|
||||
watchFile(currWatchPath + f, { interval: 250 }, async () => {
|
||||
//* Read dir
|
||||
//* ReadFiles
|
||||
files = await readdirSync(path);
|
||||
readFiles(files, path);
|
||||
});
|
||||
});
|
||||
readFiles(files, path);
|
||||
}
|
||||
|
||||
async function readFiles(files, path) {
|
||||
//* Send files to extension
|
||||
socket.emit("localPresence", {
|
||||
files: await Promise.all(
|
||||
files.map(f => {
|
||||
if (extname(f) === ".json")
|
||||
return {
|
||||
file: f,
|
||||
contents: JSON.parse(readFileSync(`${path}/${f}`).toString())
|
||||
};
|
||||
else if (extname(f) === ".js")
|
||||
return {
|
||||
file: f,
|
||||
contents: readFileSync(`${path}/${f}`).toString()
|
||||
};
|
||||
else return;
|
||||
})
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
export async function openFileDialog() {
|
||||
//* Open file dialog
|
||||
//* If user cancels
|
||||
//* Unwatch all still watched files
|
||||
//* Watch directory
|
||||
let filePaths = await dialog.showOpenDialogSync(null, {
|
||||
title: "Select Presence Folder",
|
||||
message:
|
||||
"Please select the folder that contains the presence you want to load.\n(metadata.json, presence.js, iframe.js)",
|
||||
buttonLabel: "Load Presence",
|
||||
properties: ["openDirectory"]
|
||||
});
|
||||
if (typeof filePaths === "undefined") {
|
||||
//* Show debug
|
||||
//* return
|
||||
info("Presence load canceled.");
|
||||
return;
|
||||
}
|
||||
info(`Watching ${filePaths[0]}`);
|
||||
if (presenceDevWatchedFiles.length > 0)
|
||||
await Promise.all(
|
||||
presenceDevWatchedFiles.map(f => unwatchFile(currWatchPath + f))
|
||||
);
|
||||
|
||||
watchDir(filePaths[0]);
|
||||
}
|
||||
33
src/managers/settingsManager.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import ElectronStore from "electron-store";
|
||||
import { tray } from "./trayManager";
|
||||
import { update as updateAutoLaunch } from "./launchManager";
|
||||
import { platform } from "os";
|
||||
import { info } from "../util/debug";
|
||||
|
||||
//* Import custom types
|
||||
import ExtensionSettings from "../../@types/PreMiD/ExtensionSettings";
|
||||
|
||||
//* Export and set default settings
|
||||
export let settings = new ElectronStore({
|
||||
defaults: {
|
||||
autoLaunch: true
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Update settings of app
|
||||
* @param extensionSettings Settings from extension
|
||||
*/
|
||||
export function update(extensionSettings: ExtensionSettings) {
|
||||
//* Show debug
|
||||
//* remove title if disabled
|
||||
//* Update autolaunch if updated
|
||||
//* Save Settings
|
||||
info("Updated settings");
|
||||
if (!extensionSettings.titleMenubar && platform() === "darwin")
|
||||
tray.setTitle("");
|
||||
if (settings.get("autoLaunch") != extensionSettings.autoLaunch) {
|
||||
settings.set("autoLaunch", extensionSettings.autoLaunch);
|
||||
updateAutoLaunch();
|
||||
}
|
||||
}
|
||||
77
src/managers/socketManager.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import socketIo from "socket.io";
|
||||
import { createServer, Server } from "http";
|
||||
import { app, dialog } from "electron";
|
||||
import { success, error } from "../util/debug";
|
||||
import { update as updateSettings } from "./settingsManager";
|
||||
import { openFileDialog } from "./presenceDevManager";
|
||||
import { setActivity, clearActivity, destroy } from "./discordManager";
|
||||
|
||||
export let io: socketIo.Server;
|
||||
export let socket: socketIo.Socket;
|
||||
export let server: Server;
|
||||
|
||||
export function init() {
|
||||
return new Promise(resolve => {
|
||||
//* Create server
|
||||
//* create SocketIo server, don't server client
|
||||
//* Try to listen to port 3020
|
||||
//* If that fails/some other error happens run socketError
|
||||
//* If someone connects to socket socketConnection
|
||||
server = createServer();
|
||||
io = socketIo(server, { serveClient: false });
|
||||
server.listen(3020, () => {
|
||||
//* Resolve promise
|
||||
//* Debug info
|
||||
resolve();
|
||||
success("Opened socket");
|
||||
});
|
||||
server.on("error", socketError);
|
||||
io.on("connection", socketConnection);
|
||||
});
|
||||
}
|
||||
|
||||
function socketConnection(cSocket: socketIo.Socket) {
|
||||
//* Show debug
|
||||
//* Set exported socket letiable to current socket
|
||||
//* Handle setActivity event
|
||||
//* Handle clearActivity event
|
||||
//* Handle settingsUpdate
|
||||
//* Handle presenceDev
|
||||
//* Handle version request
|
||||
//* Once socket user disconnects run cleanup
|
||||
success("Socket connection");
|
||||
socket = cSocket;
|
||||
socket.on("setActivity", setActivity);
|
||||
socket.on("clearActivity", clearActivity);
|
||||
socket.on("settingUpdate", updateSettings);
|
||||
socket.on("selectLocalPresence", openFileDialog);
|
||||
socket.on("getVersion", () =>
|
||||
socket.emit("receiveVersion", app.getVersion().replace(/[\D]/g, ""))
|
||||
);
|
||||
socket.once("disconnect", () => {
|
||||
//* Show debug
|
||||
//* Destroy all open RPC connections
|
||||
error("Socket disconnection.");
|
||||
destroy();
|
||||
});
|
||||
}
|
||||
|
||||
//* Runs on socket errors
|
||||
function socketError(e: any) {
|
||||
//* Show debug
|
||||
//* If port in use
|
||||
error(e.message);
|
||||
if (e.code === "EADDRINUSE") {
|
||||
//* Focus app
|
||||
//* Show error dialog
|
||||
//* Exit app afterwards
|
||||
app.focus();
|
||||
dialog.showErrorBox(
|
||||
"Oh noes! Port error...",
|
||||
`${app.name} could not bind to port ${
|
||||
e.port
|
||||
}.\nIs ${app.name} running already?`
|
||||
);
|
||||
app.quit();
|
||||
}
|
||||
}
|
||||
26
src/managers/trayManager.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Menu, Tray } from "electron";
|
||||
import { join } from "path";
|
||||
|
||||
//* Export tray
|
||||
//* Export trayContextMenu
|
||||
export let tray: Tray;
|
||||
export let trayContextMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
role: "quit"
|
||||
}
|
||||
]);
|
||||
|
||||
/**
|
||||
* Create tray
|
||||
*/
|
||||
export function init() {
|
||||
//* Return promise resolves to Tray
|
||||
return new Promise<Tray>(function(resolve) {
|
||||
//* Create Tray
|
||||
//* Set its context menu
|
||||
//* Resolve promise
|
||||
tray = new Tray(join(__dirname, "../assets/tray/IconTemplate.png"));
|
||||
tray.setContextMenu(trayContextMenu);
|
||||
resolve(tray);
|
||||
});
|
||||
}
|
||||
5897
src/package-lock.json
generated
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"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,92 +0,0 @@
|
||||
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"
|
||||
});
|
||||
|
||||
//* Define needed variables
|
||||
var lastKeepAliveSwitch = 0
|
||||
|
||||
//* Keep alive check to automatically remove presence if browser not running/not using YT
|
||||
setInterval(keepAliveCheck, 1000)
|
||||
|
||||
async function keepAliveCheck() {
|
||||
if (lastKeepAliveSwitch > 0) {
|
||||
setupServices.forEach(service => {
|
||||
service.rpc.destroy()
|
||||
})
|
||||
setupServices = []
|
||||
serviceLogins = []
|
||||
if(PLATFORM == "darwin") TRAY.setTitle("");
|
||||
}
|
||||
lastKeepAliveSwitch += 1
|
||||
}
|
||||
|
||||
//* 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'))
|
||||
})
|
||||
|
||||
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)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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,22 +0,0 @@
|
||||
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)
|
||||
@@ -1,22 +0,0 @@
|
||||
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;
|
||||
})
|
||||
}
|
||||