Compare commits

...

731 Commits

Author SHA1 Message Date
Kasper Rynning-Tønnesen
116cb3f68d Nicer transitions. Closes #518 2019-08-07 16:24:52 +02:00
Kasper Rynning-Tønnesen
13bc8cb0ba Merge pull request #523 from zoff-music/feat/added-by-suggest
Added by on suggested songs
2019-08-07 16:13:18 +02:00
Kasper Rynning-Tønnesen
9ed72c0cc0 Added by on suggested songs 2019-08-07 16:12:56 +02:00
Kasper Rynning-Tønnesen
ad8bc0c05b Fixed remote issue 2019-08-05 12:24:59 +02:00
Kasper Rynning-Tønnesen
9993a377b8 Merge pull request #522 from zoff-music/fix/520
Other channel is the counter and deciding part
2019-07-31 13:18:39 +02:00
Kasper Rynning-Tønnesen
0213c5fe0a Other channel is the counter and deciding part 2019-07-31 13:18:17 +02:00
Kasper Rynning-Tønnesen
d820b2daba Merge pull request #521 from zoff-music/fix/520
Closes #520
2019-07-31 13:03:12 +02:00
Kasper Rynning-Tønnesen
3739a15049 Closes #520 2019-07-31 13:02:41 +02:00
Kasper Rynning-Tønnesen
cba874510b Merge pull request #517 from zoff-music/fix/404
Fix/404
2019-07-29 15:56:07 +02:00
Kasper Rynning-Tønnesen
b3a7b95fd6 Removed some commented code 2019-07-29 15:54:41 +02:00
Kasper Rynning-Tønnesen
f9b05c11e0 Fix for 404 not routing to 404 page 2019-07-29 15:52:27 +02:00
Kasper Rynning-Tønnesen
e8d49c77df Merge pull request #516 from zoff-music/fix/viewcount
Fix for view-count
2019-07-26 13:12:55 +02:00
Kasper Rynning-Tønnesen
bd9815927b Fix for view-count 2019-07-26 13:12:35 +02:00
Kasper Rynning-Tønnesen
07164153b0 Merge pull request #515 from zoff-music/refactor/prettifier
Styling-fixes
2019-07-26 10:46:00 +02:00
Kasper Rynning-Tønnesen
116a1e8905 Styling-fixes 2019-07-26 10:45:39 +02:00
Kasper Rynning-Tønnesen
206321a46f Merge pull request #514 from zoff-music/refactor/prettifier
Refactor/prettifier
2019-07-26 10:27:18 +02:00
Kasper Rynning-Tønnesen
4b0680e366 MOved some more elements around 2019-07-26 10:26:50 +02:00
Kasper Rynning-Tønnesen
bcb5641f90 Somewhat prettier css 2019-07-26 10:23:55 +02:00
Kasper Rynning-Tønnesen
460d0138f0 Merge pull request #512 from zoff-music/refactor/prettifier
More prettier missing files
2019-07-26 08:51:06 +02:00
Kasper Rynning-Tønnesen
6289f73844 More prettier missing files 2019-07-26 08:50:35 +02:00
Kasper Rynning-Tønnesen
4d96763545 Merge pull request #511 from zoff-music/refactor/prettifier
Prettified som more files and fixed some logging of missing files so …
2019-07-26 08:46:42 +02:00
Kasper Rynning-Tønnesen
6ed67ffee6 Prettified som more files and fixed some logging of missing files so they are more similar in fashion 2019-07-26 08:46:03 +02:00
Kasper Rynning-Tønnesen
d3e72202ce Merge pull request #510 from zoff-music/fix/audit
Removed gulp-util and lodash-template
2019-07-25 16:54:42 +02:00
Kasper Rynning-Tønnesen
6369c55252 Removed gulp-util and lodash-template 2019-07-25 16:54:12 +02:00
Kasper Rynning-Tønnesen
74b18b99a0 Merge pull request #509 from zoff-music/refactor/audit-fixes
Refactor/audit fixes
2019-07-25 16:51:25 +02:00
Kasper Rynning-Tønnesen
c144119395 Removed unused npm packages 2019-07-25 16:50:59 +02:00
Kasper Rynning-Tønnesen
384d3bb6c6 Removed a log 2019-07-25 16:50:10 +02:00
Kasper Rynning-Tønnesen
d65fa07ce1 Merge pull request #508 from zoff-music/refactor/audit-fixes
Fixed some audit-issues, and started using prettify
2019-07-25 16:48:06 +02:00
Kasper Rynning-Tønnesen
1594bafb60 Fixed some audit-issues, and started using prettify 2019-07-25 16:47:01 +02:00
Kasper Rynning-Tønnesen
9d6a07dbec log 2019-07-09 12:48:04 +02:00
Kasper Rynning-Tønnesen
5a769810c0 Fix for handlebars vulnerability 2019-06-14 18:34:31 +02:00
Kasper Rynning-Tønnesen
9e6f302d45 Pride thingy 2019-06-14 18:33:22 +02:00
Kasper Rynning-Tønnesen
ba98375bf9 Aborting sending info if not updated 2019-05-15 23:00:41 +02:00
Kasper Rynning-Tønnesen
17a998fcbc Added song_change update for local-mode also 2019-05-15 22:53:17 +02:00
Kasper Rynning-Tønnesen
6cfab8aebc Fix for error on video not always skipping 2019-05-15 22:46:44 +02:00
Kasper Rynning-Tønnesen
7b002c528e Error testing 2019-05-15 21:58:31 +02:00
Kasper Rynning-Tønnesen
684c49c7c6 Licensed/copyright 2019-05-15 21:44:35 +02:00
Kasper Rynning-Tønnesen
d7d1416c9c Update list.js 2019-05-03 15:12:25 +02:00
Kasper Rynning-Tønnesen
4301c989f0 Update search.js 2019-04-27 13:04:48 +02:00
Kasper Rynning-Tønnesen
725c8e5385 trying a fix for import not working corectly 2019-04-27 12:59:11 +02:00
Kasper Rynning-Tønnesen
a5174c9b92 Update main.js 2019-04-23 16:01:52 +02:00
Kasper Rynning-Tønnesen
702c585bb8 Update channel.js 2019-04-23 16:01:47 +02:00
Kasper Rynning-Tønnesen
0b3357e752 Update frontpage.js 2019-04-23 16:01:43 +02:00
Kasper Rynning-Tønnesen
e59f332689 Update embed.js 2019-04-23 16:01:39 +02:00
Kasper Rynning-Tønnesen
72cfbe26c1 Update remotecontroller.js 2019-04-23 16:01:34 +02:00
Kasper Rynning-Tønnesen
39d10745a1 Fix for error-video in list not being updated when replaced 2019-04-06 17:50:45 +02:00
Kasper Rynning-Tønnesen
632bcef2ef Moved some names around 2019-04-06 15:48:04 +02:00
Kasper Rynning-Tønnesen
4106b30ac4 Merge pull request #506 from zoff-music/fix/502
Fix for suggested videos not correctly being added. Closes #502
2019-04-06 15:28:55 +02:00
Kasper Rynning-Tønnesen
7941614ae7 Merge pull request #505 from zoff-music/feature/501
Closes #501
2019-04-06 15:28:33 +02:00
Kasper Rynning-Tønnesen
cfd0dc88fd Fix for suggested videos not correctly being added. Closes #502 2019-04-06 15:28:06 +02:00
Kasper Rynning-Tønnesen
76dea850a6 Closes #501 2019-04-06 15:20:10 +02:00
Kasper Rynning-Tønnesen
1e7153b995 FIx for status-error crashing on routingFunction in app.js 2019-04-06 15:11:06 +02:00
Kasper Rynning-Tønnesen
80db2f7068 Merge pull request #504 from zoff-music/fix/better-error-skip
Fix/better error skip
2019-04-06 14:37:48 +02:00
Kasper Rynning-Tønnesen
7bab1fac16 Correctly fetching video-info on error for youtube 2019-04-06 14:37:03 +02:00
Kasper Rynning-Tønnesen
50704be17b Better handling of errors in videos, only removing if an error is found, else a regular skip is performed 2019-04-06 14:28:18 +02:00
Kasper Rynning-Tønnesen
9725f1d7f1 Merge pull request #500 from zoff-music/fix/admin-name-xss
Escape characters in admin-module also
2019-03-22 18:10:17 +01:00
Kasper Rynning-Tønnesen
580ab99a72 Escape characters in admin-module also 2019-03-22 18:09:47 +01:00
Kasper Rynning-Tønnesen
b3c8540bd6 Merge pull request #499 from zoff-music/fix/495
Fix for sizing in channelsettings
2019-03-22 18:05:33 +01:00
Kasper Rynning-Tønnesen
7b0e6a0fdf Fix for sizing in channelsettings 2019-03-22 18:05:08 +01:00
Kasper Rynning-Tønnesen
54c7009fda Merge pull request #498 from zoff-music/fix/xss-local
Fix for issue #496 and #497
2019-03-22 18:02:29 +01:00
Kasper Rynning-Tønnesen
4fab433f61 Fix for issue #496 and #497 2019-03-22 18:01:56 +01:00
Kasper Rynning-Tønnesen
e2b2801728 Merge pull request #494 from zoff-music/feature/cool
Feature/cool
2019-03-22 06:19:11 +01:00
Kasper Rynning-Tønnesen
212eeedf02 Merge pull request #493 from zoff-music/fix/positioning-remote-logo
Fix positioning of icon on remote-page
2019-03-22 06:18:32 +01:00
Kasper Rynning-Tønnesen
9e8eed8dab Merge pull request #491 from zoff-music/fix/host-mode-resizing
Fix for host-mode not correctly resizing
2019-03-22 06:17:06 +01:00
Kasper Rynning-Tønnesen
449e7cc8d1 Cooler hidden feature 2019-03-21 21:32:47 +01:00
Kasper Rynning-Tønnesen
86fe2ba6c9 Fix positioning of icon on remote-page 2019-03-21 21:26:28 +01:00
Kasper Rynning-Tønnesen
a97aa6d3e3 Closes #489 2019-03-21 21:01:30 +01:00
Kasper Rynning-Tønnesen
4c3bb9b436 Forcing pause icon to be active on play 2019-03-21 20:54:45 +01:00
Kasper Rynning-Tønnesen
d95ce57910 Added a function to log last logs, in case of any crashes 2019-03-21 20:53:44 +01:00
Kasper Rynning-Tønnesen
f3547cc028 Fix for addd from other playlist crashing 2019-03-21 20:26:27 +01:00
Kasper Rynning-Tønnesen
8123c71185 Merge pull request #490 from zoff-music/feature/security-headers
Feature/security headers
2019-03-21 20:17:06 +01:00
Kasper Rynning-Tønnesen
dc3bd12f69 Better headers 2019-03-21 20:16:39 +01:00
Kasper Rynning-Tønnesen
c8614bef52 Testing feature-police 2019-03-21 20:11:42 +01:00
Kasper Rynning-Tønnesen
dfc49156f5 No crash 2019-03-21 20:03:26 +01:00
Kasper Rynning-Tønnesen
7c57dfaf98 Added more security headers 2019-03-21 20:01:56 +01:00
Kasper Rynning-Tønnesen
017ecc0b94 Merge pull request #487 from zoff-music/fix/security-alerts
Update install-script
2019-03-10 22:28:35 +01:00
Kasper Rynning-Tønnesen
1ea1221a76 Update install-script 2019-03-10 22:27:49 +01:00
Kasper Rynning-Tønnesen
2f3edfb64c Merge pull request #486 from zoff-music/fix/security-alerts
Fix for issues
2019-03-10 22:20:52 +01:00
Kasper Rynning-Tønnesen
a8363ebbd2 Fix for issues 2019-03-10 22:19:52 +01:00
Kasper Rynning-Tønnesen
55a0b678d6 Merge pull request #485 from zoff-music/fix/483
Fix and close #483
2019-03-10 21:51:24 +01:00
Kasper Rynning-Tønnesen
b703a6ae76 Fix and close #483 2019-03-10 21:50:49 +01:00
Kasper Rynning-Tønnesen
bdcd8a197c Merge pull request #484 from zoff-music/feature/title-filter-advanced
Add advanced title filter
2019-03-10 21:42:22 +01:00
Kasper Rynning-Tønnesen
e58f569f80 Add advanced title filter
- Timeout filter-requests based on computer instead of api
2019-03-10 21:40:58 +01:00
Kasper Rynning-Tønnesen
cff3faf820 Merge pull request #481 from zoff-music/feature/tags
Dont pasue on space in field
2019-03-02 18:29:21 +01:00
Kasper Rynning-Tønnesen
d5c39b467e Dont pasue on space in field 2019-03-02 18:28:46 +01:00
Kasper Rynning-Tønnesen
ad06f3c9d7 Merge pull request #477 from zoff-music/feature/tags
Feature/tags
2019-03-02 13:34:43 +01:00
Kasper Rynning-Tønnesen
c22a7cf32b Buttons top and bottom for filtering pagination 2019-03-02 13:34:18 +01:00
Kasper Rynning-Tønnesen
1c05a1c3b2 Previous/next pagination working 2019-03-02 13:23:57 +01:00
Kasper Rynning-Tønnesen
af92dd0e3a Better sizing on filtering field and button, and search-button in list positioning 2019-03-01 08:25:05 +01:00
Kasper Rynning-Tønnesen
73b971cab2 Add GA event for opening advanced filtering 2019-02-28 23:19:11 +01:00
Kasper Rynning-Tønnesen
ba7c5f4f54 Focus and blur modal-input for advanced filtering 2019-02-28 23:08:02 +01:00
Kasper Rynning-Tønnesen
1921090255 Add check for point at first or last element 2019-02-28 22:58:19 +01:00
Kasper Rynning-Tønnesen
23954faa86 Merge branch 'master' into feature/tags 2019-02-28 22:51:39 +01:00
Kasper Rynning-Tønnesen
066480458d Tags functionality 2019-02-28 22:51:22 +01:00
Kasper Rynning-Tønnesen
4ba9d0bca3 Update list_change.js 2019-02-28 17:02:20 +01:00
Kasper Rynning-Tønnesen
f5a992dde0 Update list_change.js 2019-02-27 17:07:53 +01:00
Kasper Rynning-Tønnesen
db89a5c55b Merge pull request #478 from zoff-music/fix/strict-skip-error
Fix for strict-skip errors not working correctly
2019-02-26 21:49:13 +01:00
Kasper Rynning-Tønnesen
b3dc00abb1 Fix for strict-skip errors not working correctly 2019-02-26 21:48:45 +01:00
Kasper Rynning-Tønnesen
c3bfac72c6 Modal and filter somewhat working 2019-02-26 21:42:30 +01:00
Kasper Rynning-Tønnesen
1a66320029 More correct error message on no video find with those tags 2019-02-25 00:01:04 +01:00
Kasper Rynning-Tønnesen
6c0c110b68 Added search-endpoint for fetching by category 2019-02-24 23:59:00 +01:00
Kasper Rynning-Tønnesen
c66d6efa76 Tags add for add songs and in api 2019-02-24 23:39:36 +01:00
Kasper Rynning-Tønnesen
46f0882a63 Merge branch 'master' into feature/tags 2019-02-24 23:02:36 +01:00
Kasper Rynning-Tønnesen
e111c9e2ca Merge pull request #473 from zoff-music/fix/suggested-soundcloud
Fix for suggestions not correctly work for soundcloud
2019-02-24 23:02:26 +01:00
Kasper Rynning-Tønnesen
c8fec1894b Fix for suggestions not correctly work for soundcloud 2019-02-24 23:01:42 +01:00
Kasper Rynning-Tønnesen
8970092017 Started tags work 2019-02-24 22:44:59 +01:00
Kasper Rynning-Tønnesen
a6e064072c Merge pull request #472 from zoff-music/feature/playlist-search-button
Added button for searching in channel
2019-02-24 22:17:52 +01:00
Kasper Rynning-Tønnesen
991b8f9ef2 Added button for searching in channel 2019-02-24 22:14:54 +01:00
Kasper Rynning-Tønnesen
903532b2fd etter response on empty-list skip-try, and add log for debugging when server crashes on change_song 2019-01-30 19:45:21 +01:00
Kasper Rynning-Tønnesen
4589299f52 Validating that there actually is songs in the channel 2019-01-30 13:42:18 +01:00
Kasper Rynning-Tønnesen
b7eeefa634 Merge pull request #470 from zoff-music/fix/intelligent-mobile
Fix for mobile intelligent list
2019-01-22 18:21:16 +01:00
Kasper Rynning-Tønnesen
436732dd39 Fix for mobile not correctly handling intelligent lists on joining from frontpage 2019-01-22 18:20:11 +01:00
Kasper Rynning-Tønnesen
9b79242246 Add focus on add to other list button click 2019-01-22 17:56:22 +01:00
Kasper Rynning-Tønnesen
d359c8e0c2 Fixed issue with add to other list form not correctly handling variables 2019-01-22 17:52:12 +01:00
Kasper Rynning-Tønnesen
9bd4fcdf32 Update listeners.js 2019-01-22 16:01:16 +01:00
Kasper Rynning-Tønnesen
e830a4143b Forcing intelligent to be set when changed on mobile 2019-01-22 06:23:00 +01:00
Kasper Rynning-Tønnesen
8bd3f123a5 Merge pull request #468 from zoff-music/feature/add-song-to-other-list
Feature/add song to other list
2019-01-21 17:43:22 +01:00
Kasper Rynning-Tønnesen
3dcae3f2fd Merge pull request #469 from zoff-music/feature/intelligent-mobile
Added intelligent playlist on mobile also
2019-01-21 17:43:07 +01:00
Kasper Rynning-Tønnesen
b9113a905d Added intelligent playlist on mobile also 2019-01-21 17:42:09 +01:00
Kasper Rynning-Tønnesen
57b1f3b818 Better styling and a header 2019-01-21 17:30:54 +01:00
Kasper Rynning-Tønnesen
ab6f1648e6 Working on mobile and desktop 2019-01-20 13:01:58 +01:00
Kasper Rynning-Tønnesen
dd9a58f810 Added add song to other list from one list button in the controls bar 2019-01-19 16:58:42 +01:00
Kasper Rynning-Tønnesen
3f8f6fc12e Merge pull request #467 from zoff-music/feature/less-notifs
Hidden some notifictions
2019-01-19 13:12:57 +01:00
Kasper Rynning-Tønnesen
61aec92617 Hidden some notifictions 2019-01-19 13:12:23 +01:00
Kasper Rynning-Tønnesen
5f3c7890a0 Added button to add song to other playlist 2019-01-19 13:08:59 +01:00
Kasper Rynning-Tønnesen
6e4d5d0249 Merge pull request #466 from zoff-music/feature/strict-skip-api
Feature/strict skip api
2019-01-19 12:58:21 +01:00
Kasper Rynning-Tønnesen
34bb46c4af Fixed issue with people being able to skip multiple times 2019-01-19 12:47:13 +01:00
Kasper Rynning-Tønnesen
49ddf5d2c0 Working api-endpoint for strict-skipping 2019-01-19 12:24:55 +01:00
Kasper Rynning-Tønnesen
07e44ec947 Started preliminary testing with local api-key. So far working.
- Need to fix response statuscodes
- Need to test when strict not enabled
- Need to test why sIO is not working
- Need to test with userpassword
- Need to add a secret way of storing allowed api-key
2019-01-18 17:35:33 +01:00
Kasper Rynning-Tønnesen
6385971d3b Adding switch for chromecast info being hidden or not (#463) 2019-01-18 17:03:38 +01:00
Kasper Rynning-Tønnesen
1ff0de31bc Started api 2019-01-18 17:02:28 +01:00
Kasper Rynning-Tønnesen
770e25a88a Added some info for the strict skipping 2019-01-17 22:31:33 +01:00
Kasper Rynning-Tønnesen
21988a2883 Started functionality for strict-skipping 2019-01-17 21:52:17 +01:00
Kasper Rynning-Tønnesen
b9b71ff7db Fix for adding playlists not working 2019-01-17 20:02:10 +01:00
Kasper Rynning-Tønnesen
d28e14448a Updated placeholder 2019-01-17 08:24:46 +01:00
Kasper Rynning-Tønnesen
bcd00aa93e Fix for empty list import (#459)
* Fix for empty list import

* Flex on enable also
2019-01-15 21:11:16 +01:00
Kasper Rynning-Tønnesen
03ca6a9f77 Fix/total listeners disabled chat (#458)
* Testing some leavers

* Logging before and after namechange

* Testing callback even on chat disabled

* Fixed issue with channels with disabled chat not adding to total listeners

* Fixed potential issue with joining a channel with disabled chat broadcasts it
2019-01-15 19:04:08 +01:00
Kasper Rynning-Tønnesen
b2e9050960 Merge pull request #457 from zoff-music/fix/skip-playlist-mover
Fixing an issue with skipping a song sometimes changes the pagination
2019-01-14 19:22:06 +01:00
Kasper Rynning-Tønnesen
697c7fa88f Fixing an issue with skipping a song sometimes changes the pagination 2019-01-14 19:21:31 +01:00
Kasper Rynning-Tønnesen
b0e3532845 Merge pull request #456 from zoff-music/fix/user-ban
Fixes banning users
2019-01-04 11:53:39 +01:00
Kasper Rynning-Tønnesen
d1bcf3ec14 Fixes banning users, Closes #454 2019-01-04 11:53:07 +01:00
Kasper Rynning-Tønnesen
5086fb56e6 Update functions.js 2018-12-28 22:45:51 +01:00
Kasper Rynning-Tønnesen
f3aabc3db1 Update main.js 2018-12-28 22:43:18 +01:00
Kasper Rynning-Tønnesen
9051b5b99f Update helpers.js 2018-12-28 22:39:41 +01:00
Kasper Rynning-Tønnesen
d8bf064c50 Merge pull request #452 from zoff-music/fix/fireplace-and-host-size
Updated QR-code size in hostmode and fullscreen fireplace player when…
2018-12-09 15:41:56 +01:00
Kasper Rynning-Tønnesen
3f63b580ed Updated QR-code size in hostmode and fullscreen fireplace player when enabled on fullscreen 2018-12-09 15:41:10 +01:00
Kasper Rynning-Tønnesen
2a06329235 Merge pull request #451 from zoff-music/fix/embed-size
Fixed issue with title in embedded player and preview-player
2018-12-05 14:47:01 +01:00
Kasper Rynning-Tønnesen
69c2dc6a33 Fixed issue with title in embedded player
- And issue with embedded preview re-appearing when changing values even though the user clicked stop
2018-12-05 14:46:11 +01:00
Kasper Rynning-Tønnesen
dbee7398bb Merge pull request #450 from zoff-music/fix/encoding
Fixed encoding issue on autocomplete and input send
2018-12-04 12:51:03 +01:00
Kasper Rynning-Tønnesen
9a1a341bfa Fixed encoding issue on autocomplete and input send 2018-12-04 12:50:27 +01:00
Kasper Rynning-Tønnesen
664a5de46d Merge pull request #449 from zoff-music/fix/encoding
Trying a fix for encoding issues occuring from time to time
2018-12-04 12:40:28 +01:00
Kasper Rynning-Tønnesen
cad2292269 Trying a fix for encoding issues occuring from time to time 2018-12-04 12:40:06 +01:00
Kasper Rynning-Tønnesen
14d8ef51bb Merge pull request #448 from zoff-music/fix/client
Fixed issue with client.zoff.me not working correctly
2018-12-02 15:25:31 +01:00
Kasper Rynning-Tønnesen
ef1fed0410 Fixed issue with client.zoff.me not working correctly 2018-12-02 15:25:01 +01:00
Kasper Rynning-Tønnesen
ddb55baa3b Removing adds since Google don't like our site 2018-11-30 18:01:49 +01:00
Kasper Rynning-Tønnesen
a88da7ccf2 Update suggested video by users to send correct parameters 2018-11-28 17:06:44 +01:00
Kasper Rynning-Tønnesen
69f0007e6d Merge pull request #447 from zoff-music/feature/ads
Testing adsense fix
2018-11-27 12:44:38 +01:00
Kasper Rynning-Tønnesen
932bd6b9f2 Testing adsense fix 2018-11-27 12:40:59 +01:00
Kasper Rynning-Tønnesen
be4a3dcdc7 Merge pull request #446 from zoff-music/feature/ads
Feature/ads
2018-11-27 08:58:53 +01:00
Kasper Rynning-Tønnesen
1849727ff8 Correct syntax 2018-11-27 08:58:31 +01:00
Kasper Rynning-Tønnesen
10f9ff87da Not including our adcode 2018-11-27 08:57:55 +01:00
Kasper Rynning-Tønnesen
e21865422d Added examplefile 2018-11-27 08:57:03 +01:00
Kasper Rynning-Tønnesen
e4ca2bb8cf Trying adsense to help serverbills 2018-11-27 08:56:13 +01:00
Kasper Rynning-Tønnesen
77d215f89f Adding dash to pageview for prettier google-analytics listing 2018-11-23 12:43:26 +01:00
Kasper Rynning-Tønnesen
810c2fe24b Added inherit on backgroundcolor of title/search to avoid previous rule be triggered 2018-11-23 12:38:49 +01:00
Kasper Rynning-Tønnesen
ae17ae92be Hover only affecting title/search instead all nav ul li elements 2018-11-23 12:36:37 +01:00
Kasper Rynning-Tønnesen
c679a3ae42 Removed update affecting settings and unintended elements 2018-11-23 12:34:33 +01:00
Kasper Rynning-Tønnesen
cbba57ba05 Updated how title is darkened on hover 2018-11-23 12:30:39 +01:00
Kasper Rynning-Tønnesen
f8ca3ce2a5 Not updating title on empty title 2018-11-20 15:33:30 +01:00
Kasper Rynning-Tønnesen
39449c5f48 Showing title by default on load 2018-11-20 15:30:21 +01:00
Kasper Rynning-Tønnesen
e8ca18d98e modified open-graph type depending on url 2018-11-20 13:36:27 +01:00
Kasper Rynning-Tønnesen
866d6a9b26 Merge branch 'master' of github.com:zoff-music/zoff 2018-11-20 11:40:07 +01:00
Kasper Rynning-Tønnesen
7ec8884fce Updated embedded player with title at top 2018-11-20 11:39:56 +01:00
Kasper Rynning-Tønnesen
e85c2ce390 Backgroundcolor -> Background 2018-11-16 10:52:13 +01:00
Kasper Rynning-Tønnesen
496c1cdeb2 Added ga event for import/exporting soundcloud and zoff 2018-11-07 11:39:26 +01:00
Kasper Rynning-Tønnesen
98f6f9b6fb Merge pull request #443 from zoff-music/feature/static-color
Adding GA-tracker on switching between static and dynamic backgroundc…
2018-11-07 09:26:23 +01:00
Kasper Rynning-Tønnesen
03935eb958 Adding GA-tracker on switching between static and dynamic backgroundcolor 2018-11-07 09:26:02 +01:00
Kasper Rynning-Tønnesen
949de761a3 Merge pull request #442 from zoff-music/feature/static-color
Feature/static color
2018-11-06 13:57:41 +01:00
Kasper Rynning-Tønnesen
e16135d616 Added missing settings-file 2018-11-06 13:57:21 +01:00
Kasper Rynning-Tønnesen
be9d74d271 Allowing users to define their player's colors 2018-11-06 13:53:37 +01:00
Kasper Rynning-Tønnesen
2003383967 Not including suggested songs in fetching of playlist 2018-11-05 14:50:06 +01:00
Kasper Rynning-Tønnesen
22ee6b6fcf Update about.handlebars 2018-11-05 13:31:28 +01:00
Kasper Rynning-Tønnesen
6ba4c86ccf Merge pull request #441 from zoff-music/fix/pip-close
Removing PiP-player fully on close player
2018-10-29 15:06:49 +01:00
Kasper Rynning-Tønnesen
59dce08075 Removing PiP-player fully on close player 2018-10-29 15:06:28 +01:00
Kasper Rynning-Tønnesen
8aeb80dfe5 Merge pull request #440 from zoff-music/feature/client-settings
Moved some settings to a separate accordion to gather stuff more
2018-10-29 15:01:04 +01:00
Kasper Rynning-Tønnesen
d684efe405 Removed enable remote from enable remote switch 2018-10-29 14:59:26 +01:00
Kasper Rynning-Tønnesen
f0fc0ed424 Merge pull request #439 from zoff-music/refactor/ajax-client-load
Fixed ajax-crash on userpass-protected lists
2018-10-29 14:57:52 +01:00
Kasper Rynning-Tønnesen
d4628c6e8f Fixed ajax-crash on userpass-protected lists 2018-10-29 14:57:25 +01:00
Kasper Rynning-Tønnesen
dde0586ca3 Moved some settings to a separate accordion to gather stuff mroe 2018-10-29 14:47:58 +01:00
Kasper Rynning-Tønnesen
3998817b62 Merge pull request #438 from zoff-music/feature/intelligent-list
Intelligent list
2018-10-29 14:31:55 +01:00
Kasper Rynning-Tønnesen
d315851667 Updated info-text about intelligent some 2018-10-29 14:31:43 +01:00
Kasper Rynning-Tønnesen
73cec39de0 Changed so accordion for intelligent-playlist is not hidden on small player on desktops 2018-10-29 14:29:41 +01:00
Kasper Rynning-Tønnesen
6443974c7a Added functionality for intelligent playlist, making voting and such easier on many listeners 2018-10-29 14:19:59 +01:00
Kasper Rynning-Tønnesen
6cbf7a211e Started intelligent-list feature 2018-10-29 12:30:43 +01:00
Kasper Rynning-Tønnesen
4dcd03d042 fixed issue with copying suggested song-link 2018-10-25 11:43:28 +02:00
Kasper Rynning-Tønnesen
bb4b21581d Revert last update 2018-10-25 11:34:02 +02:00
Kasper Rynning-Tønnesen
d53beee004 Added load-indicator for adminpanel 2018-10-25 11:32:23 +02:00
Kasper Rynning-Tønnesen
c4211bcab5 Fixed resize-function triggering too often 2018-10-25 11:21:52 +02:00
Kasper Rynning-Tønnesen
0aa6910f25 Updating preview-element on refresh of variables, and updated preview-button 2018-10-25 10:36:23 +02:00
Kasper Rynning-Tønnesen
1a7ff97e7e better placement of song title on embedded player 2018-10-24 19:41:53 +02:00
Kasper Rynning-Tønnesen
a898f418a7 Showing title 2018-10-24 18:32:13 +02:00
Kasper Rynning-Tønnesen
dbce64547f Forcing a padding to not hide any button-elements 2018-10-24 15:45:17 +02:00
Kasper Rynning-Tønnesen
c81fde167f Correct placement 2018-10-24 15:41:36 +02:00
Kasper Rynning-Tønnesen
cef50a07ef Embed playlist navigate buttons 2018-10-24 15:39:42 +02:00
Kasper Rynning-Tønnesen
269c1cadb7 Merge pull request #437 from zoff-music/feature/preview-embed
Added option to preview embedded element
2018-10-24 13:11:26 +02:00
Kasper Rynning-Tønnesen
67b98d12ad Added option to preview embedded element 2018-10-24 13:10:56 +02:00
Kasper Rynning-Tønnesen
5a352a875e Merge pull request #436 from zoff-music/feature/better-embed-player
limiting number of elements showed on small embedded player
2018-10-24 12:51:41 +02:00
Kasper Rynning-Tønnesen
9229fc07cf limiting number of elements showed on small embedded player 2018-10-24 12:51:16 +02:00
Kasper Rynning-Tønnesen
9b0f84fbe4 Merge pull request #435 from zoff-music/feature/better-embed-player
Feature/better embed player
2018-10-24 12:46:15 +02:00
Kasper Rynning-Tønnesen
082282dd23 Removed logs 2018-10-24 12:45:46 +02:00
Kasper Rynning-Tønnesen
8e1e28f219 Small screen support small playlist-elements better 2018-10-24 12:45:21 +02:00
Kasper Rynning-Tønnesen
f80dbb9d80 Merge pull request #434 from zoff-music/feature/better-embed-player
better embed player on small screens
2018-10-24 12:41:27 +02:00
Kasper Rynning-Tønnesen
8376148195 better embed player on small screens 2018-10-24 12:40:47 +02:00
Kasper Rynning-Tønnesen
4b571b65f0 Style-fixes for export/import from soundcloud 2018-10-23 14:17:37 +02:00
Kasper Rynning-Tønnesen
a649f3835a Update README.md 2018-10-23 13:36:22 +02:00
Kasper Rynning-Tønnesen
112eb1e939 Update README.md 2018-10-23 13:36:06 +02:00
Kasper Rynning-Tønnesen
d44f93faa8 Merge pull request #433 from zoff-music/feature/export-soundcloud
Feature/export soundcloud
2018-10-23 13:33:16 +02:00
Kasper Rynning-Tønnesen
8d7ce5b7c1 Removed unused code 2018-10-23 13:31:04 +02:00
Kasper Rynning-Tønnesen
20e7dbb4fc Adding decription on export 2018-10-23 13:28:45 +02:00
Kasper Rynning-Tønnesen
4f26163cdf Better colors for export-buttons 2018-10-23 13:26:03 +02:00
Kasper Rynning-Tønnesen
fcea76fd01 Logging number of tracks found 2018-10-23 13:21:35 +02:00
Kasper Rynning-Tønnesen
e2de81e412 logging correctly 2018-10-23 13:19:18 +02:00
Kasper Rynning-Tønnesen
d7b4cbcbd1 Logging if debug enabled 2018-10-23 13:17:04 +02:00
Kasper Rynning-Tønnesen
10cca16415 Avoid changing local variables used in list 2018-10-23 13:14:45 +02:00
Kasper Rynning-Tønnesen
f0e1e26cc3 Added not found and logging 2018-10-23 13:10:11 +02:00
Kasper Rynning-Tønnesen
ceb70a0996 Testing issues where SC_player not initialized correctly 2018-10-23 13:06:24 +02:00
Kasper Rynning-Tønnesen
8f09eb8d66 Typo 2018-10-23 13:02:56 +02:00
Kasper Rynning-Tønnesen
d74a6694a8 Visual loop and not exported elements 2018-10-23 13:02:16 +02:00
Kasper Rynning-Tønnesen
a6e49995e6 Trying with another name for the list 2018-10-23 12:53:52 +02:00
Kasper Rynning-Tønnesen
57674c17e7 Trying to create new list for test purposes 2018-10-23 12:52:12 +02:00
Kasper Rynning-Tønnesen
00a2740406 Not looping higher than list 2018-10-23 12:49:27 +02:00
Kasper Rynning-Tønnesen
2b020ad4c2 Looping through whole list 2018-10-23 12:48:01 +02:00
Kasper Rynning-Tønnesen
2f62b40ce4 Parsing to int 2018-10-23 12:47:10 +02:00
Kasper Rynning-Tønnesen
351daf74c5 Logging more data 2018-10-23 12:45:44 +02:00
Kasper Rynning-Tønnesen
e41b98fbdb Stopping at full loop for exporting 2018-10-23 12:43:22 +02:00
Kasper Rynning-Tønnesen
74d5f958e5 Correct soundcloud-player reference 2018-10-23 12:38:23 +02:00
Kasper Rynning-Tønnesen
8f985d5da0 Enabled importing again 2018-10-23 12:35:58 +02:00
Kasper Rynning-Tønnesen
71f1826435 Exporting to soundcloud tests 2018-10-23 12:33:27 +02:00
Kasper Rynning-Tønnesen
8f46eabbaf merged 2018-10-23 12:05:51 +02:00
Kasper Rynning-Tønnesen
03f68d3131 Catch for function not existing 2018-10-23 12:03:28 +02:00
Kasper Rynning-Tønnesen
fb4e190b6e Merge pull request #432 from zoff-music/feature/soundcloud-api-import
Feature/soundcloud api import
2018-10-22 14:34:46 +02:00
Kasper Rynning-Tønnesen
32a741b147 Updated panel some 2018-10-22 14:33:54 +02:00
Kasper Rynning-Tønnesen
88bb45f390 Fixed callback code to reflect search also 2018-10-22 13:35:04 +02:00
Kasper Rynning-Tønnesen
a42e340819 Printing data back 2018-10-22 13:33:26 +02:00
Kasper Rynning-Tønnesen
7ef4ea7079 Soundcloud updates for private lists testing 2018-10-22 13:32:00 +02:00
Kasper Rynning-Tønnesen
00641806c8 Merge pull request #431 from zoff-music/feature/better-embed-oauth-link
Fixed issue with allow autoplay not being included
2018-10-07 12:55:23 +02:00
Kasper Rynning-Tønnesen
048255cb1d Fixed issue with allow autoplay not being included 2018-10-07 12:54:39 +02:00
Kasper Rynning-Tønnesen
3c1a485f83 Merge pull request #430 from zoff-music/feature/better-embed-oauth-link
Moved oauth callback to /api/oauth and embed to /api/embed, with util…
2018-10-07 12:51:26 +02:00
Kasper Rynning-Tønnesen
2e8da96706 Moved oauth callback to /api/oauth and embed to /api/embed, with utilizing the search in url 2018-10-07 12:48:41 +02:00
Kasper Rynning-Tønnesen
5333b4bc13 Fixed issue with player on frontpage on smaller windows overlapped where it shouldn't 2018-10-05 12:37:55 +02:00
Kasper Rynning-Tønnesen
f3c079726a updated donate text thingy 2018-10-03 16:31:40 +02:00
Kasper Rynning-Tønnesen
8e3a3f679e Fixed issue with adding to the end of string on 429 error 2018-10-02 15:35:20 +02:00
Kasper Rynning-Tønnesen
90538377fb Creating local variable for error sent when too meny requests performed without api-key 2018-10-02 15:27:01 +02:00
Kasper Rynning-Tønnesen
f34ac9699e Merge pull request #429 from zoff-music/feature/api-updates
Adding timeout for usual get-requests when not authenticated with a t…
2018-10-02 15:10:23 +02:00
Kasper Rynning-Tønnesen
b802a0af3d Only adding info on where to get api-token if not authorized with an api-token 2018-10-02 15:10:08 +02:00
Kasper Rynning-Tønnesen
7ca8d91a0e added info on where to get api-key 2018-10-02 15:08:20 +02:00
Kasper Rynning-Tønnesen
aa74a10305 Adding timeout for usual get-requests when not authenticated with a token 2018-10-02 15:03:27 +02:00
Kasper Rynning-Tønnesen
b537aa1af6 Prettier hover on small player for titles 2018-10-01 15:53:50 +02:00
Kasper Rynning-Tønnesen
bed3febcfa Sizing of container for remote-control-id on mobile in channel 2018-10-01 15:36:01 +02:00
Kasper Rynning-Tønnesen
a57b3eb8be Included projects in list_settings.js 2018-10-01 13:53:25 +02:00
Kasper Rynning-Tønnesen
cb8ae6ba2c Added second sort-field for title on api 2018-10-01 13:51:53 +02:00
Kasper Rynning-Tønnesen
ee2eea789c Merge pull request #428 from zoff-music/feature/small-player-frontpage
Fixed following issues caused
2018-09-29 17:01:09 +02:00
Kasper Rynning-Tønnesen
645edee211 Fixed following issues caused 2018-09-29 17:00:29 +02:00
Kasper Rynning-Tønnesen
a08ad36d86 Merge pull request #427 from zoff-music/feature/small-player-frontpage
Prettier small player on frontpage when playing soundcloud
2018-09-29 15:56:43 +02:00
Kasper Rynning-Tønnesen
81dd783609 Prettier small player on frontpage when playing soundcloud 2018-09-29 15:56:17 +02:00
Kasper Rynning-Tønnesen
ab8e53d1e0 I am getting many commits because i forget what im doing 2018-09-29 14:19:33 +02:00
Kasper Rynning-Tønnesen
7e75af57eb CHanged default embed-code-color to zoff-color 2018-09-29 14:17:58 +02:00
Kasper Rynning-Tønnesen
8faac03fb4 Visual improvements to page-buttons on embedded 2018-09-29 14:08:21 +02:00
Kasper Rynning-Tønnesen
d5a1858765 Added screenshot of embedded/iframed player 2018-09-29 13:48:11 +02:00
Kasper Rynning-Tønnesen
106eff4f24 Prettifyied embedded player somewhat 2018-09-29 13:45:27 +02:00
Kasper Rynning-Tønnesen
8f1a67a513 Undone error with soundcloud on load in embedded mode 2018-09-29 13:15:19 +02:00
Kasper Rynning-Tønnesen
0ccdcd2845 Merge pull request #426 from zoff-music/fix/embedded-next
Fix/embedded next
2018-09-29 13:05:12 +02:00
Kasper Rynning-Tønnesen
d3d03fdb15 Forgot to send the current video on next song 2018-09-29 13:04:50 +02:00
Kasper Rynning-Tønnesen
642f8c273d Trying fix for sending next song 2018-09-29 12:46:17 +02:00
Kasper Rynning-Tønnesen
ac5ed63cb9 Added a prettier loader to embedded players 2018-09-29 11:34:35 +02:00
Kasper Rynning-Tønnesen
695a4f3648 Reword skipping in channel, allowing the whole channel to be skipped each second 2018-09-29 10:36:44 +02:00
Kasper Rynning-Tønnesen
ae05344aa1 Skip timeout not on channel but on user 2018-09-28 13:58:10 +02:00
Kasper Rynning-Tønnesen
2563b3c4f1 Added timeout for skips for 1 second 2018-09-28 13:56:05 +02:00
Kasper Rynning-Tønnesen
b3825bd093 Linking soundcloud without client-id, but it wont work 2018-09-28 13:10:45 +02:00
Kasper Rynning-Tønnesen
3053e61985 Somewhat better copy-link for soundcloud, still needs work 2018-09-28 13:09:13 +02:00
Kasper Rynning-Tønnesen
1ad6272331 Merge pull request #425 from zoff-music/feature/timeout-update
Updated index for timeout-api and timing out connections, not cookies
2018-09-28 12:38:01 +02:00
Kasper Rynning-Tønnesen
ea6ba9e1c1 Updated index for timeout-api and timing out connections, not cookies 2018-09-28 12:36:42 +02:00
Kasper Rynning-Tønnesen
b792f48523 Merge pull request #424 from zoff-music/feature/timeout-playlist-add
Added function for timing out playlist adds when not logged in
2018-09-28 12:26:33 +02:00
Kasper Rynning-Tønnesen
5ab5f0f079 Added function for timing out playlist adds when not logged in 2018-09-28 12:24:37 +02:00
Kasper Rynning-Tønnesen
c0abda2e73 Fixed search-tabs hiding but not the results on empty search 2018-09-28 11:35:09 +02:00
Kasper Rynning-Tønnesen
de619211fc Merge pull request #423 from zoff-music/refactor/aggregates
Added a own aggregates file
2018-09-28 11:14:14 +02:00
Kasper Rynning-Tønnesen
693e30f273 Added a own aggregates file
- Aggregate and project missing fields
- Updated how channels are created, to add the new fields
2018-09-28 11:13:49 +02:00
Kasper Rynning-Tønnesen
3102893e15 Adding thumbnail/description and rules in api requests 2018-09-28 10:54:41 +02:00
Kasper Rynning-Tønnesen
0a11ff09d9 Added preview of rules/description 2018-09-28 10:46:42 +02:00
Kasper Rynning-Tønnesen
0c86b0e9ee Fixing issue where change-info button was visible before it was supposed to 2018-09-28 10:36:04 +02:00
Kasper Rynning-Tønnesen
e26d277460 Merge pull request #422 from zoff-music/refactor/materialize-1.0
Updated to use materializecss 1.0.0 instead of -rc2.0
2018-09-28 10:29:03 +02:00
Kasper Rynning-Tønnesen
4aff6360c0 Merge pull request #421 from zoff-music/feature/rules
Added function for rules
2018-09-28 10:27:40 +02:00
Kasper Rynning-Tønnesen
a52d355456 Updating lists when rules/description and thumbnail is updated 2018-09-28 10:27:14 +02:00
Kasper Rynning-Tønnesen
b152209f05 Updated to use materializecss 1.0.0 instead of -rc2.0 2018-09-27 22:07:41 +02:00
Kasper Rynning-Tønnesen
0b3e7177b1 Added function for rules, and moved thumbnail/data somewhat around for better readability 2018-09-27 22:03:23 +02:00
Kasper Rynning-Tønnesen
5a84a4bc70 Added endpoint for deleting chat-users and UI for it on admin-panel 2018-09-27 14:46:59 +02:00
Kasper Rynning-Tønnesen
1f3c98a91b Merge pull request #419 from zoff-music/fix/updated-packages
Updated packages
2018-09-27 13:34:55 +02:00
Kasper Rynning-Tønnesen
f8d06c1744 Updated packages 2018-09-27 13:34:20 +02:00
Kasper Rynning-Tønnesen
473dde44f1 Fixed issue with soundcloud player not hiding on small device on pausing 2018-09-27 13:18:05 +02:00
Kasper Rynning-Tønnesen
fe727c075f Merge pull request #418 from zoff-music/feature/disable-chat
Fallback for channels without togglechat settings
2018-09-27 13:02:08 +02:00
Kasper Rynning-Tønnesen
6996472854 Fallback for channels without togglechat settings 2018-09-27 13:01:33 +02:00
Kasper Rynning-Tønnesen
34616c2d53 Merge pull request #416 from zoff-music/feature/disable-chat
Added settings for disabling chat in a channel
2018-09-27 12:58:08 +02:00
Kasper Rynning-Tønnesen
2686074b66 Fixed prefix-positioning on firefox 2018-09-27 12:55:13 +02:00
Kasper Rynning-Tønnesen
5878f57b64 Merge branch 'master' into feature/disable-chat 2018-09-27 12:48:04 +02:00
Kasper Rynning-Tønnesen
de9a43c653 Merge pull request #417 from zoff-music/feature/kick-ban-in-chat
Added ban/unban functionality in chat
2018-09-27 12:30:18 +02:00
Kasper Rynning-Tønnesen
c0d36b368c Merge branch 'master' into feature/kick-ban-in-chat 2018-09-27 12:29:26 +02:00
Kasper Rynning-Tønnesen
2117f839ac Merge branch 'master' into feature/disable-chat 2018-09-27 12:08:20 +02:00
Kasper Rynning-Tønnesen
c0864b3311 Merge pull request #415 from zoff-music/security/improved-security
Better hiding of passwords, hiding cookie-logins better
2018-09-27 11:45:36 +02:00
Kasper Rynning-Tønnesen
510ba13b32 Added settings handlebars 2018-09-27 11:44:50 +02:00
Kasper Rynning-Tønnesen
e1781c4f11 Added ban/unban functionality in chat 2018-09-27 11:43:00 +02:00
Kasper Rynning-Tønnesen
24ca0832ba Hiding chat-settings if not logged in as admin 2018-09-27 10:29:07 +02:00
Kasper Rynning-Tønnesen
6740da6d5c Only setting chat settings if it is sent 2018-09-27 10:25:03 +02:00
Kasper Rynning-Tønnesen
c12e633729 Added settings for disabling chat in a channel 2018-09-26 23:29:36 +02:00
Kasper Rynning-Tønnesen
d501e645f6 Removing userpass if userpass isnt needed on login on channel 2018-09-26 22:50:58 +02:00
Kasper Rynning-Tønnesen
c136199269 Better hiding of passwords, hiding cookie-logins better 2018-09-26 22:33:33 +02:00
Kasper Rynning-Tønnesen
7ab5d4f399 Removed logging after finding issue with channels and leaves 2018-09-26 20:09:54 +02:00
Kasper Rynning-Tønnesen
f19992060e More data 2018-09-26 19:57:51 +02:00
Kasper Rynning-Tønnesen
8d3dd93436 Logging left-channel also 2018-09-26 19:56:28 +02:00
Kasper Rynning-Tønnesen
16dd0e34ad Sending and logging end object also 2018-09-26 19:53:02 +02:00
Kasper Rynning-Tønnesen
4a79ae1b7d Trying end-video fix 2018-09-26 19:52:37 +02:00
Kasper Rynning-Tønnesen
f08f63edfc Updated a small part for logging 2018-09-26 19:42:17 +02:00
Kasper Rynning-Tønnesen
58bc3d138f More specific number of dollaass 2018-09-26 14:07:43 +02:00
Kasper Rynning-Tønnesen
0bef149269 more ensurance id is string 2018-09-26 11:30:05 +02:00
Kasper Rynning-Tønnesen
4e874b79fb Fixed issue with some songs being added as integer ids 2018-09-26 10:47:42 +02:00
Kasper Rynning-Tønnesen
9e18b85218 Added help-button in chat 2018-09-26 10:31:17 +02:00
Kasper Rynning-Tønnesen
f1b3ccad98 Update README.md 2018-09-25 23:59:18 +02:00
Kasper Rynning-Tønnesen
d843ee0993 Merge pull request #411 from zoff-music/fix/better-widget-soundcloud-load
Fix/better widget soundcloud load
2018-09-25 22:59:12 +02:00
Kasper Rynning-Tønnesen
0965060ce3 Added fix for embedded also 2018-09-25 22:58:49 +02:00
Kasper Rynning-Tønnesen
751b5008fb Better loading of iframe/soundcloud sdk
- Mitigates some errors on load
2018-09-25 22:57:04 +02:00
Kasper Rynning-Tønnesen
c86509b899 Correctly importing with https 2018-09-25 20:30:31 +02:00
Kasper Rynning-Tønnesen
6f1689ccb0 Merge pull request #410 from zoff-music/feature/less-intrusive-iframe
Made the iframed less intrusive
2018-09-25 20:25:39 +02:00
Kasper Rynning-Tønnesen
ce3ed5f191 Made the iframed less intrusive 2018-09-25 20:25:15 +02:00
Kasper Rynning-Tønnesen
7ced63c98d Merge pull request #409 from zoff-music/fix/soundcloud_load
Fixing issues with soundcloudplayer not understanding it is loaded
2018-09-25 18:17:25 +02:00
Kasper Rynning-Tønnesen
e24711ea1c Merge pull request #408 from zoff-music/fix/viewcount-crash
Statistics-crash-mitigation
2018-09-25 18:17:04 +02:00
Kasper Rynning-Tønnesen
742ecfaa1d Fixing issues with soundcloudplayer not understanding it is loaded 2018-09-25 18:15:43 +02:00
Kasper Rynning-Tønnesen
82c6910e62 Statistics-crash-mitigation 2018-09-25 17:57:06 +02:00
Kasper Rynning-Tønnesen
9d0c5173c4 Merge pull request #407 from zoff-music/feature/fallback-soundcloud-player
Fallback with iframed soundcloud player for rate-limit reached
2018-09-25 17:51:05 +02:00
Kasper Rynning-Tønnesen
39a2fc6532 Fallback with iframed soundcloud player for rate-limit reached
- Messes up history of current tab, but it's better than not playing any music
2018-09-25 17:49:49 +02:00
Kasper Rynning-Tønnesen
e5221ad88b Added skip for rate-limit reached on soundcloud 2018-09-25 13:25:45 +02:00
Kasper Rynning-Tønnesen
e050e19c5f Merge branch 'master' of github.com:zoff-music/zoff 2018-09-25 12:56:22 +02:00
Kasper Rynning-Tønnesen
febbc0cfdc Removed debug-log 2018-09-25 12:28:23 +02:00
Kasper Rynning-Tønnesen
9cb1ec72db Removed debug-log 2018-09-25 12:28:23 +02:00
Kasper Rynning-Tønnesen
ec90e9332c Merge pull request #405 from zoff-music/refactor/crash-start-clustered
Better nice-fail if files are missing, and more correctly start non-c…
2018-09-25 12:27:23 +02:00
Kasper Rynning-Tønnesen
83bb97b2f3 Merge pull request #405 from zoff-music/refactor/crash-start-clustered
Better nice-fail if files are missing, and more correctly start non-c…
2018-09-25 12:27:23 +02:00
Kasper Rynning-Tønnesen
3e3ef4d6d2 Better nice-fail if files are missing, and more correctly start non-clustered run 2018-09-25 12:26:55 +02:00
Kasper Rynning-Tønnesen
c32ccc63eb Better nice-fail if files are missing, and more correctly start non-clustered run 2018-09-25 12:26:55 +02:00
Kasper Rynning-Tønnesen
ef30540756 Merge pull request #404 from zoff-music/fix/find-div-width
fixed width of find-div
2018-09-25 11:12:40 +02:00
Kasper Rynning-Tønnesen
dd5f8b6a4b Merge pull request #404 from zoff-music/fix/find-div-width
fixed width of find-div
2018-09-25 11:12:40 +02:00
Kasper Rynning-Tønnesen
12d3e0ddc9 fixed width of find-div 2018-09-25 11:09:52 +02:00
Kasper Rynning-Tønnesen
82b69350c7 fixed width of find-div 2018-09-25 11:09:52 +02:00
Kasper Rynning-Tønnesen
db9a63be48 Hiding settings in iframed player 2018-09-24 00:09:54 +02:00
Kasper Rynning-Tønnesen
54a9a0ed4f Hiding settings in iframed player 2018-09-24 00:09:54 +02:00
Kasper Rynning-Tønnesen
e92d4ed61a Removing some functions from iframed-player 2018-09-24 00:09:05 +02:00
Kasper Rynning-Tønnesen
38b1a1330c Removing some functions from iframed-player 2018-09-24 00:09:05 +02:00
Kasper Rynning-Tønnesen
498e8e4676 Delete rewrite.js 2018-09-23 23:23:48 +02:00
Kasper Rynning-Tønnesen
0b197dca64 Delete rewrite.js 2018-09-23 23:23:48 +02:00
Kasper Rynning-Tønnesen
a499fa9001 Delete addtype.js 2018-09-23 23:23:33 +02:00
Kasper Rynning-Tønnesen
26bfca1bb9 Delete addtype.js 2018-09-23 23:23:33 +02:00
Kasper Rynning-Tønnesen
eb379e6f5c Disabled samesite value for now for avoiding cookies not being removed on iframe-load 2018-09-23 21:48:25 +02:00
Kasper Rynning-Tønnesen
06f960e3d4 Disabled samesite value for now for avoiding cookies not being removed on iframe-load 2018-09-23 21:48:25 +02:00
Kasper Rynning-Tønnesen
ced5e52223 Open modal always when small player/iframed, close after 5 seconds 2018-09-23 21:37:19 +02:00
Kasper Rynning-Tønnesen
aa871e80e2 Open modal always when small player/iframed, close after 5 seconds 2018-09-23 21:37:19 +02:00
Kasper Rynning-Tønnesen
b121151240 Removed copythingy from iframed element 2018-09-23 21:32:57 +02:00
Kasper Rynning-Tønnesen
990966b18e Removed copythingy from iframed element 2018-09-23 21:32:57 +02:00
Kasper Rynning-Tønnesen
58e5def473 Added modal for mobile automatically open in iframe 2018-09-23 21:30:13 +02:00
Kasper Rynning-Tønnesen
fa189967e7 Added modal for mobile automatically open in iframe 2018-09-23 21:30:13 +02:00
Kasper Rynning-Tønnesen
1fef8a9831 Added join-link for iframes 2018-09-23 21:15:10 +02:00
Kasper Rynning-Tønnesen
df2bb4809e Added join-link for iframes 2018-09-23 21:15:10 +02:00
Kasper Rynning-Tønnesen
1d061e213f Merge branch 'master' of github.com:zoff-music/zoff 2018-09-23 19:57:42 +02:00
Kasper Rynning-Tønnesen
f5e9424161 Merge branch 'master' of github.com:zoff-music/zoff 2018-09-23 19:57:42 +02:00
Kasper Rynning-Tønnesen
5593c5272a Fix for functions not existing in functions file 2018-09-23 19:57:14 +02:00
Kasper Rynning-Tønnesen
ce7c821082 Fix for functions not existing in functions file 2018-09-23 19:57:14 +02:00
Kasper Rynning-Tønnesen
9e6d8be32e Merge pull request #403 from zoff-music/fix/embed-code-generation
Fixed issue with embed-code generating faulty
2018-09-23 13:13:14 +02:00
Kasper Rynning-Tønnesen
a107a740fe Merge pull request #403 from zoff-music/fix/embed-code-generation
Fixed issue with embed-code generating faulty
2018-09-23 13:13:14 +02:00
Kasper Rynning-Tønnesen
8e714c838f Fixed issue with embed-code generating faulty 2018-09-23 13:12:50 +02:00
Kasper Rynning-Tønnesen
40e40ad298 Fixed issue with embed-code generating faulty 2018-09-23 13:12:50 +02:00
Kasper Rynning-Tønnesen
47e40ccb13 Merge pull request #402 from zoff-music/fix/youtube-export
Fixed issues with youtube-exporting
2018-09-23 12:11:30 +02:00
Kasper Rynning-Tønnesen
07bce2c87b Merge pull request #402 from zoff-music/fix/youtube-export
Fixed issues with youtube-exporting
2018-09-23 12:11:30 +02:00
Kasper Rynning-Tønnesen
d791273b15 Fixed issues with youtube-exporting 2018-09-23 12:11:03 +02:00
Kasper Rynning-Tønnesen
c133b60f19 Fixed issues with youtube-exporting 2018-09-23 12:11:03 +02:00
Kasper Rynning-Tønnesen
f629c4b362 Merge pull request #401 from zoff-music/fix/soundcloud-not-end
Fixed issue where soundcloud couldn't end song
2018-09-23 11:56:57 +02:00
Kasper Rynning-Tønnesen
5eade73f54 Merge pull request #401 from zoff-music/fix/soundcloud-not-end
Fixed issue where soundcloud couldn't end song
2018-09-23 11:56:57 +02:00
Kasper Rynning-Tønnesen
4e9b9d63c3 Fixed issue where soundcloud couldn't end song 2018-09-23 11:56:30 +02:00
Kasper Rynning-Tønnesen
5aa5c2b572 Fixed issue where soundcloud couldn't end song 2018-09-23 11:56:30 +02:00
Kasper Rynning-Tønnesen
21ff54c070 Also setting opacity to 1 on bufering when not mobile 2018-09-22 20:55:00 +02:00
Kasper Rynning-Tønnesen
7f729c22fd Also setting opacity to 1 on bufering when not mobile 2018-09-22 20:55:00 +02:00
Kasper Rynning-Tønnesen
31f53e6e32 Merge pull request #400 from zoff-music/fix/session-guid
Sending GUID/session based on connection if no cookie exists for socket.io
2018-09-22 18:25:58 +02:00
Kasper Rynning-Tønnesen
6f5532c37e Merge pull request #400 from zoff-music/fix/session-guid
Sending GUID/session based on connection if no cookie exists for socket.io
2018-09-22 18:25:58 +02:00
Kasper Rynning-Tønnesen
0a205ed714 Sending GUID/session based on connection if no cookie exists for socket.io 2018-09-22 18:25:18 +02:00
Kasper Rynning-Tønnesen
a426cd4ea5 Sending GUID/session based on connection if no cookie exists for socket.io 2018-09-22 18:25:18 +02:00
Kasper Rynning-Tønnesen
9f1e7ca347 Not logging debug-messages for forcing chat-name 2018-09-22 17:25:03 +02:00
Kasper Rynning-Tønnesen
dde755a2a7 Not logging debug-messages for forcing chat-name 2018-09-22 17:25:03 +02:00
Kasper Rynning-Tønnesen
0c3ced98f2 Merge branch 'master' of github.com:zoff-music/zoff 2018-09-22 17:13:53 +02:00
Kasper Rynning-Tønnesen
c3bb5c133e Merge branch 'master' of github.com:zoff-music/zoff 2018-09-22 17:13:53 +02:00
Kasper Rynning-Tønnesen
0cfa24af2f Prettyer close-icon for PiP mode 2018-09-22 17:13:44 +02:00
Kasper Rynning-Tønnesen
99a03d2314 Prettyer close-icon for PiP mode 2018-09-22 17:13:44 +02:00
Kasper Rynning-Tønnesen
4b7bb87ebf Added logging for testing why/what urls crash the cookies 2018-09-22 17:01:36 +02:00
Kasper Rynning-Tønnesen
ee5337be3d Added logging for testing why/what urls crash the cookies 2018-09-22 17:01:36 +02:00
Kasper Rynning-Tønnesen
2572b42294 Merge pull request #399 from zoff-music/feature/iframe-small
Automatically assuming small player if in iframe
2018-09-22 16:46:28 +02:00
Kasper Rynning-Tønnesen
05c4f4b920 Merge pull request #399 from zoff-music/feature/iframe-small
Automatically assuming small player if in iframe
2018-09-22 16:46:28 +02:00
Kasper Rynning-Tønnesen
0a7ea9f0b2 Automatically assuming small player if in iframe 2018-09-22 16:45:44 +02:00
Kasper Rynning-Tønnesen
297cc10691 Automatically assuming small player if in iframe 2018-09-22 16:45:44 +02:00
Kasper Rynning-Tønnesen
62ae1ee802 Merge pull request #398 from zoff-music/fix/opacity-load
Opacity for a load
2018-09-22 16:34:03 +02:00
Kasper Rynning-Tønnesen
25c7f85203 Merge pull request #398 from zoff-music/fix/opacity-load
Opacity for a load
2018-09-22 16:34:03 +02:00
Kasper Rynning-Tønnesen
ffc1725535 Opacity for a load 2018-09-22 16:27:09 +02:00
Kasper Rynning-Tønnesen
09f3214ad6 Opacity for a load 2018-09-22 16:27:09 +02:00
Kasper Rynning-Tønnesen
2255ce861c Merge pull request #396 from zoff-music/feature/small-iframe-hash
By adding #small to the end of the link, the footer is gone and navig…
2018-09-22 16:14:46 +02:00
Kasper Rynning-Tønnesen
2244c45be3 Merge pull request #396 from zoff-music/feature/small-iframe-hash
By adding #small to the end of the link, the footer is gone and navig…
2018-09-22 16:14:46 +02:00
Kasper Rynning-Tønnesen
77da0ca1d8 Merge pull request #397 from zoff-music/feature/soundcloud-import
Soundcloud import now works, but not on private songs
2018-09-22 16:14:36 +02:00
Kasper Rynning-Tønnesen
7fdcbfe9ff Merge pull request #397 from zoff-music/feature/soundcloud-import
Soundcloud import now works, but not on private songs
2018-09-22 16:14:36 +02:00
Kasper Rynning-Tønnesen
e7bb000d47 Soundcloud import now works, but not on private songs 2018-09-22 13:04:16 +02:00
Kasper Rynning-Tønnesen
b172e39097 Soundcloud import now works, but not on private songs 2018-09-22 13:04:16 +02:00
Kasper Rynning-Tønnesen
ea01cc082a By adding #small to the end of the link, the footer is gone and navigating out is disabled 2018-09-22 11:40:13 +02:00
Kasper Rynning-Tønnesen
3f9c989b6a By adding #small to the end of the link, the footer is gone and navigating out is disabled 2018-09-22 11:40:13 +02:00
Kasper Rynning-Tønnesen
36175fbdf9 Merge pull request #395 from zoff-music/fix/name-chat-leave
Fixed issue with names on leave remaining for some reason and trying …
2018-09-21 15:54:56 +02:00
Kasper Rynning-Tønnesen
a9dd4e512b Merge pull request #395 from zoff-music/fix/name-chat-leave
Fixed issue with names on leave remaining for some reason and trying …
2018-09-21 15:54:56 +02:00
Kasper Rynning-Tønnesen
e17d3a5bf3 Fixed issue with names on leave remaining for some reason and trying fix for users without name 2018-09-21 15:52:52 +02:00
Kasper Rynning-Tønnesen
fbecb2ccd2 Fixed issue with names on leave remaining for some reason and trying fix for users without name 2018-09-21 15:52:52 +02:00
Kasper Rynning-Tønnesen
2add5d4aae Better word-break on card-reveal 2018-09-21 14:29:27 +02:00
Kasper Rynning-Tønnesen
0c6a871a46 Search-extra buttons positioning 2018-09-21 12:15:26 +02:00
Kasper Rynning-Tønnesen
90c62505a6 Merge pull request #394 from zoff-music/fix/correct-errors
Fixed some results errors
2018-09-21 12:12:39 +02:00
Kasper Rynning-Tønnesen
5018c509a3 Fixed some results errors 2018-09-20 20:18:53 +02:00
Kasper Rynning-Tønnesen
f89dd49b4b Merge pull request #393 from zoff-music/fix/api-admin-update
API-elements are correctly removed on refresh
2018-09-20 17:50:35 +02:00
Kasper Rynning-Tønnesen
12efbbcd99 API-elements are correctly removed on refresh 2018-09-20 17:49:28 +02:00
Kasper Rynning-Tønnesen
b1412d9fc3 Re-implemented color-generating of System 2018-09-20 17:09:46 +02:00
Kasper Rynning-Tønnesen
0dd5496b71 Added failsafe for /name so noone sends their password wrongly after the /login update 2018-09-20 16:54:02 +02:00
Kasper Rynning-Tønnesen
7646f5183b Fixed newly created issue of timestamps of chat 2018-09-20 16:48:42 +02:00
Kasper Rynning-Tønnesen
836f96f7b2 Visual improvements for chat 2018-09-20 16:47:12 +02:00
Kasper Rynning-Tønnesen
3055d53f27 Merge pull request #392 from zoff-music/feature/who-chat
Feature of /who and seeing the people in the channel
2018-09-20 16:33:40 +02:00
Kasper Rynning-Tønnesen
8c1985bb1a Merge pull request #391 from zoff-music/fix/no-localstorage-error
Fix for localstorage not being existing crashes the player
2018-09-20 16:32:38 +02:00
Kasper Rynning-Tønnesen
52fedde073 Fix for localstorage not being existing crashes the player 2018-09-20 16:32:09 +02:00
Kasper Rynning-Tønnesen
0f8f175aa0 Feature of /who and seeing the people in the channel 2018-09-20 16:31:14 +02:00
Kasper Rynning-Tønnesen
410b255874 Merge pull request #390 from zoff-music/feature/icon-leave-chat
Moved left_channel function to functions file, and sending icon for l…
2018-09-20 15:52:44 +02:00
Kasper Rynning-Tønnesen
7466ef7f61 Moved left_channel function to functions file, and sending icon for leaving/joining channel also 2018-09-20 15:31:37 +02:00
Kasper Rynning-Tønnesen
ef369f6ca6 Merge pull request #389 from zoff-music/fix/soundcloud-switching
Fixed issue where switching from one channel sometimes didnt switch the song
2018-09-20 14:28:45 +02:00
Kasper Rynning-Tønnesen
1a735e6557 Fixed issue where switching from one channel sometimes didnt switch the song 2018-09-20 14:27:43 +02:00
Kasper Rynning-Tønnesen
f39a063037 Merge pull request #388 from zoff-music/fix/pause-skip
Fixed and Closes #383
2018-09-20 14:15:52 +02:00
Kasper Rynning-Tønnesen
1b86ae514b Fixed and Closes #383 2018-09-20 14:15:26 +02:00
Kasper Rynning-Tønnesen
4a23770fe3 Merge pull request #387 from zoff-music/feature/no-cookies-allow
Fixed so users that has blocked cookies still are able to play
2018-09-20 13:58:14 +02:00
Kasper Rynning-Tønnesen
2d3ca3acc7 Merge pull request #386 from zoff-music/fix/list-height-embed
Fixed visual bug with list-items
2018-09-19 23:15:04 +02:00
Kasper Rynning-Tønnesen
4874d468fe Fixed visual bug where playlist-items had too little height in embedded mode 2018-09-19 23:01:06 +02:00
Kasper Rynning-Tønnesen
cc84a02cd2 Fixed so users that has blocked cookies still are able to play 2018-09-19 22:58:51 +02:00
Kasper Rynning-Tønnesen
c0bd3de5af guid undefined fallback 2018-09-19 22:28:56 +02:00
Kasper Rynning-Tønnesen
d661d99776 Trying to mitigate song-change-error 2018-09-19 11:08:22 +02:00
Kasper Rynning-Tønnesen
3101792420 Fixed small API-error with postvariables 2018-09-17 14:51:47 +02:00
Kasper Rynning-Tønnesen
e2dc9888ba Merge pull request #385 from zoff-music/feature/suggested-info
Moved suggested specific code to suggested file, and fixed issue wher…
2018-09-11 14:58:22 +02:00
Kasper Rynning-Tønnesen
950455a688 Moved suggested specific code to suggested file, and fixed issue where suggested sometimes dissapear 2018-09-11 14:57:43 +02:00
Kasper Rynning-Tønnesen
6cf484fa4e Merge pull request #384 from zoff-music/feature/suggested-info
More info on suggested songs
2018-09-11 14:00:20 +02:00
Kasper Rynning-Tønnesen
d86e403222 More info on suggested songs 2018-09-11 13:59:46 +02:00
Kasper Rynning-Tønnesen
d6cd183db3 Added fix for total_viewers count error 2018-09-04 12:45:16 +02:00
Kasper Rynning-Tønnesen
4c73b411d3 Added a padding to pagebuttons instead 2018-09-02 13:44:27 +02:00
Kasper Rynning-Tønnesen
ce15d4e0f3 Moved pagebuttons a little way down 2018-09-02 13:41:45 +02:00
Kasper Rynning-Tønnesen
f66611780d Fixed issue with pagebuttons transparent 2018-09-02 13:38:28 +02:00
Kasper Rynning-Tønnesen
cbbbd14c18 Absolute position on contextmenu 2018-09-02 13:21:22 +02:00
Kasper Rynning-Tønnesen
aade371c56 Fixed some styling for mobile
- Search-result height on mobile
- Pagebutton background on mobile
- Pagebutton-width/position
2018-09-02 13:19:03 +02:00
Kasper Rynning-Tønnesen
f3e23bb2cc Merge pull request #381 from zoff-music/refactor/name-generate
Improved how naming works on join
2018-09-01 13:06:01 +02:00
Kasper Rynning-Tønnesen
47e45c5b19 Improved how naming works on join
- XXXX changed name to YYYY doesn't happen if the user already is signed in
- Signs automatically in on frontpage join
2018-09-01 13:04:40 +02:00
Kasper Rynning-Tønnesen
6d361db3ad Added dragging om mobilesidenavn and scrolling to top on switching to chat-tab 2018-09-01 12:37:22 +02:00
Kasper Rynning-Tønnesen
05d009c1ce Merge pull request #379 from zoff-music/fix/play-pause-video-hide
Fixed issue with player on mobile
2018-08-31 12:06:50 +02:00
Kasper Rynning-Tønnesen
cb111fa9f8 Merge pull request #380 from zoff-music/fix/similar-search
Fixed issue with similar search not opening
2018-08-31 12:05:39 +02:00
Kasper Rynning-Tønnesen
f36a6b23ee Fixed issue with similar search not opening 2018-08-31 12:05:02 +02:00
Kasper Rynning-Tønnesen
5f07a8e751 Fixed issue where clicking the video-container on mobile did not hide the player 2018-08-31 11:43:44 +02:00
Kasper Rynning-Tønnesen
fe55b4dd63 Merge pull request #377 from zoff-music/fix/name-correctly-removed
Correctly remove name from users online on leave
2018-08-30 14:56:29 +02:00
Kasper Rynning-Tønnesen
327e69076c Correctly remove name from users online on leave 2018-08-30 14:54:46 +02:00
Kasper Rynning-Tønnesen
2fe0410645 Merge pull request #376 from zoff-music/fix/more-info-button
Fixed switch error on song start-end button for mobile
2018-08-30 13:39:00 +02:00
Kasper Rynning-Tønnesen
5895352240 Fixed switch error on song start-end button for mobile 2018-08-30 13:35:48 +02:00
Kasper Rynning-Tønnesen
6de4927298 Merge pull request #375 from zoff-music/fix/listeners-out
Trying some performance-enhancing stuff
2018-08-30 13:18:12 +02:00
Kasper Rynning-Tønnesen
e5696fcc49 Moved adding of listeners to a function, to be done after DOMContentLoadedEvent 2018-08-30 13:05:25 +02:00
Kasper Rynning-Tønnesen
a3b794c7bf Merge pull request #374 from zoff-music/feature/embedded-local
Added localmode for embedded players, configurable on embed-code create
2018-08-30 12:28:05 +02:00
Kasper Rynning-Tønnesen
35ef8a54b0 Added localmode for embedded players, configurable on embed-code create 2018-08-30 12:26:59 +02:00
Kasper Rynning-Tønnesen
19a38162be Fixed small chat-generate crash issue 2018-08-30 11:13:34 +02:00
Kasper Rynning-Tønnesen
20b745d78e Commented out own error-handler for now 2018-08-30 10:14:58 +02:00
Kasper Rynning-Tønnesen
49f6c7218d Added an error-test 2018-08-29 17:54:43 +02:00
Kasper Rynning-Tønnesen
b43527a6af Uncommented Windows-internet-code 2018-08-29 13:55:43 +02:00
Kasper Rynning-Tønnesen
85de9944a5 Adding a failsafe for rndName and how seeding works on crash 2018-08-29 13:49:34 +02:00
Kasper Rynning-Tønnesen
4c11618087 Merge pull request #372 from zoff-music/fix/soundcloud-load
Better soundcloud loader
2018-08-29 12:16:39 +02:00
Kasper Rynning-Tønnesen
b8470dcba8 Better soundcloud loader 2018-08-29 12:16:12 +02:00
Kasper Rynning-Tønnesen
c07dadadfa Merge pull request #371 from zoff-music/fix/pagespeed-error
Better error-handler for pagespeed unexpected error
2018-08-28 21:47:38 +02:00
Kasper Rynning-Tønnesen
185d5ef0b6 Merge pull request #370 from zoff-music/feature/prefix-positioning
Better prefix-positioning
2018-08-28 21:47:24 +02:00
Kasper Rynning-Tønnesen
9f35001bde Better error-handler for pagespeed unexpected error 2018-08-28 21:46:56 +02:00
Kasper Rynning-Tønnesen
d98121b47e Better prefix-positioning 2018-08-28 21:46:02 +02:00
Kasper Rynning-Tønnesen
1a4ba7ee1c Update README.md 2018-08-28 20:44:25 +02:00
Kasper Rynning-Tønnesen
45fa9ce233 prettier readme? 2018-08-28 20:41:40 +02:00
Kasper Rynning-Tønnesen
f35802e55b Merge pull request #369 from zoff-music/feature/cookie-info
Changed cookie-toast and added a cookie-modal
2018-08-28 19:20:24 +02:00
Kasper Rynning-Tønnesen
f290812f6d Changed cookie-toast and added a cookie-modal 2018-08-28 19:19:59 +02:00
Kasper Rynning-Tønnesen
ce27b65991 Merge pull request #368 from zoff-music/feature/guid-more-unique
Making guid somewhat more unique
2018-08-28 14:49:27 +02:00
Kasper Rynning-Tønnesen
8e9a76eb48 Making guid somewhat more unique, and not using connection, but cookie instead 2018-08-28 14:46:39 +02:00
Kasper Rynning-Tønnesen
6e09c6d59f Merge pull request #367 from zoff-music/feature/chat-name-persist
More persistent chat-names, and server handling of chat-names instead…
2018-08-28 14:34:11 +02:00
Kasper Rynning-Tønnesen
b66f70415c More persistent chat-names, and server handling of chat-names instead of client sending empty namechange request on join 2018-08-28 14:33:01 +02:00
Kasper Rynning-Tønnesen
b135c1390c More clever way of detecting if a name should be removed when user leaves 2018-08-28 13:18:22 +02:00
Kasper Rynning-Tønnesen
46996881cb Added more error-message on error fetching song-data 2018-08-28 12:54:43 +02:00
Kasper Rynning-Tønnesen
9852da491b Updated so username won't overflow. Removing username on general leave 2018-08-28 12:50:45 +02:00
Kasper Rynning-Tønnesen
f9a2169f51 Fixed thumbnail issue 2018-08-21 16:38:08 +02:00
Kasper Rynning-Tønnesen
0dd8155447 Trying to get friendly-name working again 2018-08-21 15:54:59 +02:00
Kasper Rynning-Tønnesen
f8711c78d1 Forgot where the code should be moved 2018-08-16 15:03:39 +02:00
Kasper Rynning-Tønnesen
a205972fff Got chromecasting working again with the new channel-names 2018-08-16 14:48:13 +02:00
Kasper Rynning-Tønnesen
1a21297cd3 Autoplay position fix 2018-08-16 12:56:52 +02:00
Kasper Rynning-Tønnesen
c6232aa407 Fixed player-issue in embed 2018-08-16 12:54:00 +02:00
Kasper Rynning-Tønnesen
171165e0d3 Merge pull request #366 from zoff-music/refactor/jquery-less-admin
Refactor/jquery less admin
2018-08-13 13:20:29 +02:00
Kasper Rynning-Tønnesen
44b065672d No more jquery in adminpanel 2018-08-13 13:19:24 +02:00
Kasper Rynning-Tønnesen
c699db6769 Started refactoring 2018-08-13 12:40:05 +02:00
Kasper Rynning-Tønnesen
cc60c48cc4 Fixed search crashing in client-mode 2018-08-12 14:41:11 +02:00
Kasper Rynning-Tønnesen
0a8194263a Update README.md 2018-08-12 14:21:54 +02:00
Kasper Rynning-Tønnesen
643fa6bd9b added appstore images in readme 2018-08-12 14:18:13 +02:00
Kasper Rynning-Tønnesen
f0afa0dd5d Update README.md 2018-08-12 14:09:01 +02:00
Kasper Rynning-Tønnesen
0bd654364a Fixed encoding-issue with channelnames 2018-08-12 13:55:48 +02:00
Kasper Rynning-Tønnesen
29cb942630 Fixed issue with accessed sorting 2018-08-11 20:14:08 +02:00
Kasper Rynning-Tønnesen
be4c48f0ab Not showing card-reveal when list has no description 2018-08-10 12:42:57 +02:00
Kasper Rynning-Tønnesen
9a1d39ea24 Fixed JSON.parse issue with new lists on navigating 2018-08-10 12:01:29 +02:00
Kasper Rynning-Tønnesen
0337a17168 Fixed frontpage-sorting issue 2018-08-10 11:59:49 +02:00
Kasper Rynning-Tønnesen
c20da5db3b Merge pull request #365 from zoff-music/feature/instant-frontpages
Feature/instant frontpages
2018-08-10 11:51:57 +02:00
Kasper Rynning-Tønnesen
6d0acaefcb More instant frontpage-loading, and sorting frontpages on the backend for consistency 2018-08-10 11:51:28 +02:00
Kasper Rynning-Tønnesen
8c29c31449 Working updating of playlist and populating 2018-08-08 22:54:41 +02:00
Kasper Rynning-Tønnesen
689bc85a62 Started work on fetching frontpage-lists at the same time as sending the html 2018-08-08 22:21:53 +02:00
Kasper Rynning-Tønnesen
5cd8cd5864 Minify-css and remove spectrum css 2018-08-08 21:24:02 +02:00
Kasper Rynning-Tønnesen
08055bca72 Merge pull request #364 from zoff-music/revert-363-feature/load
Revert "Added a load-screen"
2018-08-08 16:32:47 +02:00
Kasper Rynning-Tønnesen
debcd787f9 Revert "Added a load-screen" 2018-08-08 16:32:22 +02:00
Kasper Rynning-Tønnesen
09f9072ec1 Merge pull request #363 from zoff-music/feature/load
Added a load-screen
2018-08-08 16:30:30 +02:00
Kasper Rynning-Tønnesen
9f641c4c96 Removed gulp-sourcemaps for now because of vulnerability 2018-08-08 16:23:12 +02:00
Kasper Rynning-Tønnesen
5af081dc9f Removed some minor logs 2018-08-08 16:21:39 +02:00
Kasper Rynning-Tønnesen
1a27945752 Added a load-screen, will test for some time and see if it helps any 2018-08-08 16:20:23 +02:00
Kasper Rynning-Tønnesen
5fd67867de Fixed soundcloud loading-issue on initial channel-load 2018-08-08 16:12:54 +02:00
Kasper Rynning-Tønnesen
8e3149c2ee Fixed some loading-perforamance for soundcloud player 2018-08-08 15:37:01 +02:00
Kasper Rynning-Tønnesen
f527f4fa83 Fixed scaling-issue when showing playlist after having it 100% width 2018-08-01 19:05:19 +02:00
Kasper Rynning-Tønnesen
7f22ff2b1d Moved SoundCloud api-key out to different config file and fixed some list-naming issues that was caused with filter.clean was performed after list-name was encoded. Closes #362 2018-08-01 16:53:26 +02:00
Kasper Rynning-Tønnesen
f4dfdb32df Fixed width-issue on mobile and color-issue of title on mobile 2018-07-28 15:23:17 +02:00
Kasper Rynning-Tønnesen
c7de4bd5e3 Scaling fixes for whole site, and prettier search-loader 2018-07-27 15:56:03 +02:00
Kasper Rynning-Tønnesen
f021808d8b Fixed issue with playlist seeking with no list, seeking at statechangen for youtube and resizing on frontpage crash 2018-07-25 23:21:38 +02:00
Kasper Rynning-Tønnesen
1e6e507362 Fixed scaling issue on mobile when playing, and fixed embed crashes 2018-07-25 07:20:24 +02:00
Kasper Rynning-Tønnesen
2219e14f86 Playlist-play-pause resize coherent. Closes #355 2018-07-24 23:53:48 +02:00
Kasper Rynning-Tønnesen
dea78ffd41 moved some css out from js 2018-07-24 23:44:10 +02:00
Kasper Rynning-Tønnesen
8638685e19 Merge branch 'master' of github.com:zoff-music/zoff 2018-07-24 23:42:01 +02:00
Kasper Rynning-Tønnesen
b3da558336 bugfixes
- Fixed color-issue on local
- Fixed issue with navigating back in playlist on local
- Fixed issue with starting at the right time on local when start/end had been set
- Fixed issue where changing channel when in local, song wouldn't change
- Fixed issue on previous song not starting at the correct time in local mode
2018-07-24 23:40:35 +02:00
Your Name
4dfe5e061f catch for notificationa not existing on some devices 2018-07-15 15:44:43 -04:00
Your Name
c75537d4b8 tempfixes until I get my computer back 2018-07-15 15:34:15 -04:00
Your Name
73d31021d2 general fixes 2018-07-11 13:21:21 -04:00
Kasper Rynning-Tønnesen
d3e6af4643 Fixes 2018-07-10 16:21:16 +02:00
Kasper Rynning-Tønnesen
061b3832ae Concat before uglifying 2018-07-06 00:59:44 +02:00
Kasper Rynning-Tønnesen
0d5eec7b07 No map files maybe 2018-07-06 00:56:15 +02:00
Kasper Rynning-Tønnesen
3ca6dea8e1 Gulp fixes 2018-07-06 00:53:18 +02:00
Kasper Rynning-Tønnesen
9a66bc85ef issuefixing
- Closes #353 #352 #351 #350 #349
2018-07-05 18:32:31 +02:00
Kasper Rynning-Tønnesen
8b9069b8be fixed some issues with switching channels and host-mode enabling 2018-07-01 22:26:29 +02:00
Kasper Rynning-Tønnesen
8b513f5582 Orange select-color line 2018-07-01 21:52:41 +02:00
Kasper Rynning-Tønnesen
1cb88fa999 even more nullchecks 2018-07-01 21:46:14 +02:00
Kasper Rynning-Tønnesen
f8edd7c01a Fixing issue with embedded player suddenly showing up in debuglog 2018-07-01 21:41:31 +02:00
Kasper Rynning-Tønnesen
11509d9fbc More null-checks on wrapper 2018-07-01 21:34:56 +02:00
Kasper Rynning-Tønnesen
a9358ce360 Circular dependencies json-stringify and wrapper nullcheck 2018-07-01 21:31:59 +02:00
Kasper Rynning-Tønnesen
37aea96a95 moved sc.kill inside catch 2018-07-01 21:26:18 +02:00
Kasper Rynning-Tønnesen
ac8693e650 readded error-window and fixed player hiding on small when loading 2018-07-01 21:25:01 +02:00
Kasper Rynning-Tønnesen
8703adad14 Updated manifest.json 2018-07-01 21:08:24 +02:00
Kasper Rynning-Tønnesen
6fa293aba4 Fixed scaling issues with chat and soundcloud players on resizing 2018-06-28 16:51:31 +02:00
Kasper Rynning-Tønnesen
cf68d52afb Update to new RC of materializecss 2018-06-28 16:19:03 +02:00
Your Name
815a71b2d0 Small fix for frontpage-list icons 2018-06-27 03:57:15 -04:00
Kasper Rynning-Tønnesen
ece739a481 Fix for height of tabs on mobile 2018-06-27 07:28:11 +02:00
Your Name
4cfcd6a8a2 Updated style to have correct height for bigger player 2018-06-26 08:01:04 -04:00
Kasper Rynning-Tønnesen
5af7fe2d37 Now sending next song when asked to correctly, and to only the askee 2018-06-23 13:30:00 +02:00
Kasper Rynning-Tønnesen
8139f786ec included a typo.. 2018-06-23 12:55:35 +02:00
Kasper Rynning-Tønnesen
f9fe694987 Better viewing of playlist on playing on a small screen
- Playlist-height adapts in case video is playing, allowing users to still easily scroll through videos while it is playing
2018-06-23 12:54:11 +02:00
Kasper Rynning-Tønnesen
1995c20f4e Not setting _uI on clientside 2018-06-22 19:36:37 +02:00
Kasper Rynning-Tønnesen
23b36b1736 Trying more tests to avoid cookie being deleted 2018-06-22 18:59:19 +02:00
Kasper Rynning-Tønnesen
ef92068ea6 Fixed issue with embedded player, and trying to get better error-logs 2018-06-22 18:56:03 +02:00
Kasper Rynning-Tønnesen
3ef8a43c3c appstore and googleplay buttons 2018-06-22 07:06:22 +02:00
Kasper Rynning-Tønnesen
48099e93d8 Error log and now showing video on play in small player on desktop 2018-06-21 18:49:52 +02:00
Kasper Rynning-Tønnesen
58d26e4197 better total-users calculation hopefully 2018-06-20 14:59:18 +02:00
Kasper Rynning-Tønnesen
43d5231231 next_song listener also now 2018-06-12 19:43:53 +02:00
Kasper Rynning-Tønnesen
fc26aea9d0 Fixed typo 2018-06-11 15:55:23 +02:00
Kasper Rynning-Tønnesen
181576a0ce Showing/hiding previous button in host-mode also 2018-06-07 18:40:00 +02:00
Kasper Rynning-Tønnesen
2b42ba58d1 No pointer-events on player on host-mode 2018-06-07 15:09:23 +02:00
Kasper Rynning-Tønnesen
65fda10d64 Added some more info on host-mode 2018-06-07 14:34:17 +02:00
Kasper Rynning-Tønnesen
7fd4ff0f34 Added toast for when new song is added, and changed so the playlistpage is switched to 1 on host-mode enabling 2018-06-07 14:25:17 +02:00
Kasper Rynning-Tønnesen
38acd4db1c Re-enabled filter for badwords 2018-06-07 12:00:05 +02:00
Kasper Rynning-Tønnesen
adb5993ff7 Changing qr-code and join link when changing channel by remotecontroller 2018-06-07 11:54:51 +02:00
Kasper Rynning-Tønnesen
bc13ba9353 Merge branch 'master' of github.com:zoff-music/zoff 2018-06-07 11:43:48 +02:00
Kasper Rynning-Tønnesen
a97336ea07 Fixed small issue where client-mode crashes 2018-06-07 11:43:23 +02:00
Kasper Rynning-Tønnesen
c917740d37 Added preview of host-mode 2018-06-07 11:41:39 +02:00
Kasper Rynning-Tønnesen
8039ad1da3 Updated version of host-mode 2018-06-07 11:41:12 +02:00
Kasper Rynning-Tønnesen
f4336bdb6a Added a function to embedded player in case it thinks it needs it 2018-06-06 22:54:50 +02:00
Kasper Rynning-Tønnesen
1e016ef317 Removed some window-variables 2018-06-06 21:00:40 +02:00
Kasper Rynning-Tønnesen
3b5b302a16 Now working with loadMedia on chromecast 2018-06-06 20:28:20 +02:00
Kasper Rynning-Tønnesen
779e93cca8 Added small info on how to go out of host-mode 2018-06-06 16:21:56 +02:00
Kasper Rynning-Tønnesen
058b235eb7 Fixed issue with too many/too few playlist-elements being shown on window-resize 2018-06-06 16:19:35 +02:00
Kasper Rynning-Tønnesen
ddbd2a6381 Added missing function in embedded version 2018-06-06 16:05:01 +02:00
Kasper Rynning-Tønnesen
319125eab4 Merge pull request #348 from zoff-music/feature/host-mode
Fixed issue with hostmode navigating and embedded issue
2018-06-06 16:01:54 +02:00
Kasper Rynning-Tønnesen
6587f371de Fixed issue with hostmode navigating and embedded issue 2018-06-06 16:01:33 +02:00
Kasper Rynning-Tønnesen
3475ec87c7 Merge pull request #347 from zoff-music/feature/host-mode
Added a host-mode
2018-06-06 15:59:34 +02:00
Kasper Rynning-Tønnesen
6636c8481a Added a host-mode
- Fullscreen video + playlist
- Removed fullscreenbutton in host-mode
- Removed skip-button in host-mode
- Disabled skipping in host-mode
- Removed buttons and rightclick menus in host-mode
- Host mode for easily having a computer playing at a party without being able to modifying the currently playing video/song
2018-06-06 15:58:28 +02:00
Kasper Rynning-Tønnesen
476f44c7e2 Sending chromecast-values again on reconnect 2018-06-05 19:20:51 +02:00
Kasper Rynning-Tønnesen
8d314e150f Hiding 'waiting for video' text 2018-06-05 19:14:37 +02:00
Kasper Rynning-Tønnesen
9eed4b5955 Trying to add a log to test if code is correctly run 2018-06-05 19:10:26 +02:00
Kasper Rynning-Tønnesen
800d63be17 Tried to update to add a small temporary log 2018-06-05 19:08:11 +02:00
Kasper Rynning-Tønnesen
028782d1d4 Use best connection to chromecast 2018-06-05 19:03:21 +02:00
Kasper Rynning-Tønnesen
c134ccc058 Improved end-checking somewhat with less needed database-calls 2018-06-05 15:24:31 +02:00
Kasper Rynning-Tønnesen
48bb88d8e0 Less db-queries for settings 2018-06-05 15:08:48 +02:00
Kasper Rynning-Tønnesen
9a4ffdc57c Added trust proxy 2018-06-05 14:28:19 +02:00
Kasper Rynning-Tønnesen
15112141e0 Added another fallback for id's being empty when chromecasting 2018-06-05 12:49:51 +02:00
Kasper Rynning-Tønnesen
87aa720ea5 Merge pull request #346 from zoff-music/feature/testing-chromecast-fixes
Feature/testing chromecast fixes
2018-06-05 11:56:08 +02:00
Kasper Rynning-Tønnesen
25aca3eed3 Cleaning up logs, now working chromecast on private channel 2018-06-05 11:55:22 +02:00
Kasper Rynning-Tønnesen
031af8fe84 Created a forever loop 2018-06-05 11:07:49 +02:00
Kasper Rynning-Tønnesen
ea8f98ea07 Allowing chromecast to fetch position 2018-06-05 11:05:47 +02:00
Kasper Rynning-Tønnesen
07494a6406 Typo in variable-name 2018-06-05 11:04:05 +02:00
Kasper Rynning-Tønnesen
b55607ec1d Sending more values to get chromecast to think it is the mobile phone 2018-06-05 11:02:03 +02:00
Kasper Rynning-Tønnesen
afde001e8e Trying the flowthrough 2018-06-05 10:52:45 +02:00
Kasper Rynning-Tønnesen
9268e5e2e4 Switching two variables around 2018-06-05 10:47:10 +02:00
Kasper Rynning-Tønnesen
e873ab5406 Trying to avoid chromecast fetching position 2018-06-05 10:43:16 +02:00
Kasper Rynning-Tønnesen
b1c7d26605 Typo.. 2018-06-05 10:38:09 +02:00
Kasper Rynning-Tønnesen
bddb623787 Trying a failsafe on the cookie_id 2018-06-05 10:37:12 +02:00
Kasper Rynning-Tønnesen
3bfc7555e4 Trying to check useragent 2018-06-05 10:35:25 +02:00
Kasper Rynning-Tønnesen
bc16ce4398 Uncommented a feature 2018-06-05 10:24:09 +02:00
Kasper Rynning-Tønnesen
dde19f2225 Forgot length of element 2018-06-04 23:55:52 +02:00
Kasper Rynning-Tønnesen
200ec58773 Logging more testing to see if data is set correctly 2018-06-04 23:54:16 +02:00
Kasper Rynning-Tønnesen
2b6aee218f Sending list with also 2018-06-04 23:48:40 +02:00
Kasper Rynning-Tønnesen
82d8c0c300 Forgot to export function 2018-06-04 23:46:42 +02:00
Kasper Rynning-Tønnesen
89add8c90e Trying way of emulating cookies for chromecast 2018-06-04 23:45:25 +02:00
Kasper Rynning-Tønnesen
0cca053abe trying with sending another id 2018-06-04 23:13:13 +02:00
Kasper Rynning-Tønnesen
5bb3731323 Printing out existing users 2018-06-04 23:09:29 +02:00
Kasper Rynning-Tønnesen
0cf6ff51fa Printing tests to see what stop chromecast from joining channel 2018-06-04 23:06:42 +02:00
Kasper Rynning-Tønnesen
6797cf1a50 Testing small things 2018-06-04 22:45:28 +02:00
Kasper Rynning-Tønnesen
077e7de1b8 Trying some more debugs 2018-06-04 22:37:19 +02:00
Kasper Rynning-Tønnesen
a5b55aa692 Sending channel on mobilespecs now 2018-06-04 22:30:36 +02:00
Kasper Rynning-Tønnesen
b0a24d9946 Updates 2018-06-04 22:27:02 +02:00
Kasper Rynning-Tønnesen
7234867531 Trying to fix crash on zoff 2018-06-04 22:04:17 +02:00
Kasper Rynning-Tønnesen
72a0e7d6b0 Autoplaying celebration on api-complete 2018-06-04 16:24:30 +02:00
Kasper Rynning-Tønnesen
9a6ee1baa2 Signing up for the API work again
- Can use the same email more than once, the only difference is that it wont create a new key, only a new link to the key
2018-06-04 16:21:36 +02:00
Kasper Rynning-Tønnesen
9912e57148 Update README.md 2018-06-04 14:29:00 +02:00
Kasper Rynning-Tønnesen
fdc8943260 Changed bitcoin-address to used address 2018-06-04 13:35:53 +02:00
Kasper Rynning-Tønnesen
0a1f800659 Added a catch in promise for Jimp read 2018-06-04 11:38:04 +02:00
Kasper Rynning-Tønnesen
21947a2717 There is no function called sendstatus 2018-06-04 11:33:05 +02:00
Kasper Rynning-Tønnesen
ee6497db0b Correct way of seeking in song 2018-06-01 15:24:33 +02:00
Kasper Rynning-Tønnesen
aace2b6549 Merge branch 'master' of github.com:zoff-music/zoff 2018-06-01 15:20:26 +02:00
Kasper Rynning-Tønnesen
799bd1a223 Fixed issue with seeking too far in playlist where song has a set start-time 2018-06-01 15:20:07 +02:00
Kasper Rynning-Tønnesen
e574d7542f No GA traffic on localhost 2018-06-01 13:07:53 +02:00
Kasper Rynning-Tønnesen
9727ef2039 Sorting list and added a fallback on crash 2018-05-31 22:24:25 +02:00
Kasper Rynning-Tønnesen
b2a88014ba Removed a log 2018-05-31 17:29:18 +02:00
Kasper Rynning-Tønnesen
f6fd8caa7e Better redirect with QRcode 2018-05-31 17:26:15 +02:00
Kasper Rynning-Tønnesen
a5c984f2e0 Fixed issue with API crashes the server 2018-05-31 16:56:59 +02:00
Kasper Rynning-Tønnesen
37764a4201 Not crashing on navigating to different channel 2018-05-31 15:51:17 +02:00
Kasper Rynning-Tønnesen
f7664ac32b Fixed slashes issues in channel-names 2018-05-31 15:49:17 +02:00
Kasper Rynning-Tønnesen
ded625ae25 Better handling of og_image 2018-05-31 15:31:54 +02:00
Kasper Rynning-Tønnesen
4bdf9447f1 Updated facebook og:image 2018-05-31 15:15:17 +02:00
Kasper Rynning-Tønnesen
a4e73c8392 Bigger cards on frontpage to handle the bigger channel-names 2018-05-31 15:03:58 +02:00
Kasper Rynning-Tønnesen
96e61d7e6c Removed a small log 2018-05-31 15:03:18 +02:00
Kasper Rynning-Tønnesen
82ac25c5d2 Multi-word channel-names and API-fixes
- Spaces and signs allowed in channel-name
- Added missing functioncalls in RESTApi
2018-05-31 14:45:21 +02:00
Kasper Rynning-Tønnesen
e3c15431c5 Added possible crash-fix for subdomain-redirecting 2018-05-30 14:22:13 +02:00
Kasper Rynning-Tønnesen
b971074788 Prettier JSON and less globally exposed variables 2018-05-30 14:19:10 +02:00
Kasper Rynning-Tønnesen
68c24b6317 Sorting on sending list via socket and RESTApi when projecting 2018-05-30 11:39:20 +02:00
Kasper Rynning-Tønnesen
fcaa50cfd4 Fixed pausing with spacebar playing video on casting 2018-05-29 19:51:27 +02:00
Kasper Rynning-Tønnesen
aceaa64920 Changed default requests per second to 20 instead of 100 2018-05-29 19:43:22 +02:00
Kasper Rynning-Tønnesen
637006ab73 Fixed some unhandled exceptions 2018-05-29 19:37:22 +02:00
Kasper Rynning-Tønnesen
803ecb6a5b Trying some projections to have more consistency in data returned in RESTApi 2018-05-29 19:33:24 +02:00
Kasper Rynning-Tønnesen
adc55ee420 Updated thumbnailchecking
- Borrowing youtube 404 image for now if someone tries to trick the server to use other thumbnail than soundlcoud thumbnail when adding soundcloud song
- Setting thumbnail in db even for youtube-videos, for more consistency
2018-05-29 15:02:09 +02:00
Kasper Rynning-Tønnesen
51a5cc2b13 Merge branch 'master' of github.com:zoff-music/zoff 2018-05-29 14:38:27 +02:00
Kasper Rynning-Tønnesen
90c8ba353d Sending source on playlist add, and printing source and thumbnail api 2018-05-29 14:38:18 +02:00
Kasper Rynning-Tønnesen
4c26fff033 Flex auto on main-container 2018-05-25 16:20:16 +02:00
Kasper Rynning-Tønnesen
80ee5084a9 Removed local fonts 2018-05-24 13:31:00 +02:00
Kasper Rynning-Tønnesen
a0d01484ae Removed a jQuery file 2018-05-24 13:28:20 +02:00
Kasper Rynning-Tønnesen
120b3a0676 offline and color fixes
- ColorThief on soundcloud images
- Video title now working on offline instantiated player
- Green connected toast on connected
2018-05-24 13:22:29 +02:00
Kasper Rynning-Tønnesen
0531c65ee2 Uncommented dismissal of toasts on click until a new materializecss version is released 2018-05-24 13:00:33 +02:00
Kasper Rynning-Tønnesen
b3fbd88a44 Not hiding result-containers on short input anymore 2018-05-22 22:09:44 +02:00
Kasper Rynning-Tønnesen
dacddf6cd7 Trying to fix issue where video pauses on skipping too fast 2018-05-21 14:16:12 +02:00
Kasper Rynning-Tønnesen
de2607c403 Fix for thumbnail with soundwaves also 2018-05-20 16:34:18 +02:00
Kasper Rynning-Tønnesen
aefafa5527 Fixed small issue with waveform-thumbnails from soundcloud 2018-05-20 16:27:30 +02:00
Kasper Rynning-Tønnesen
c25b45c314 Fixed thumbnail issue 2018-05-20 16:22:24 +02:00
Kasper Rynning-Tønnesen
9db975e9e8 Fixed issue with farmhash and undefined ip 2018-05-15 12:47:39 +02:00
Kasper Rynning-Tønnesen
c11927de51 Added errormessage on faulty admin-login 2018-05-12 15:25:49 +02:00
Kasper Rynning-Tønnesen
d93c4eb2e7 Removed way of adding API-token from adminpanel 2018-05-12 15:18:30 +02:00
Kasper Rynning-Tønnesen
0f22647c9c Sorting channels before adding to selects on adminpanel 2018-05-12 15:14:55 +02:00
Kasper Rynning-Tønnesen
0a73c922c3 Fixed issues with imageblobblur and typo in io.js 2018-05-12 15:11:35 +02:00
Kasper Rynning-Tønnesen
1bd1676f82 Updated performance of adminpanel 2018-05-12 15:07:59 +02:00
Kasper Rynning-Tønnesen
1fd6427f31 Removed unused variables 2018-05-11 11:56:16 +02:00
Kasper Rynning-Tønnesen
627155cb04 Fixed issue where find-function says it found one element when it didnt 2018-05-11 11:48:24 +02:00
Kasper Rynning-Tønnesen
4e33e50955 Updated /help on chat 2018-05-10 14:01:38 +02:00
Kasper Rynning-Tønnesen
8e5624be17 farmhash for worker-id, and prefix fix on firefox 2018-05-09 12:26:22 +02:00
Kasper Rynning-Tønnesen
ee19212c81 Search and keypress issues
- Not searching on empty strings on soundcloud
- Fixed escape-button issue hiding song-title
- Escape button now works with closing find-dialog
- Fireplace-player fixes on open/close button for search
2018-05-08 14:56:27 +02:00
Kasper Rynning-Tønnesen
a0ae20b2fe Improved mobile and desktop
- Showing correct button on mobile
- Showing and hiding player-element on play/pause on mobile
- Improved playback on desktop, not stopping videoes if they're skipped while one is loading/buffering
- Small player visual-fixes on mobile
2018-05-08 09:56:55 +02:00
Kasper Rynning-Tønnesen
1233c8bb67 Merge branch 'master' of github.com:zoff-music/zoff 2018-05-07 16:16:27 +02:00
Kasper Rynning-Tønnesen
3f2b26c375 Fix for offline-mode having now_playing object updated wrongly 2018-05-07 16:16:13 +02:00
Kasper Rynning-Tønnesen
b060d74a5e Updated screenshots
Added searches with soundcloud tab in search
2018-05-07 15:52:31 +02:00
Kasper Rynning-Tønnesen
0710036ada Full-screen on soundcloud album-cover with videoonly for embedded 2018-05-07 15:46:04 +02:00
Kasper Rynning-Tønnesen
93f9109848 Fix for allow autoplay in chrome 2018-05-07 15:25:39 +02:00
Kasper Rynning-Tønnesen
1d889d5a3d Other timeout 2018-05-07 15:19:34 +02:00
Kasper Rynning-Tønnesen
38def13577 Trying with more timeout 2018-05-07 14:49:20 +02:00
Kasper Rynning-Tønnesen
f45dbe3b98 Workaround for playing if autoplay 2018-05-07 14:46:26 +02:00
Kasper Rynning-Tønnesen
653bebf8c1 Trying without the fix 2018-05-07 14:45:35 +02:00
Kasper Rynning-Tønnesen
59fcc35a47 Cheap workaround for playing embedded player 2018-05-07 14:44:17 +02:00
Kasper Rynning-Tønnesen
4d4479e067 Trying window load listener instead of DOMContentLoaded for embedded 2018-05-07 14:42:04 +02:00
Kasper Rynning-Tønnesen
3f1c45f65d Setting start and end to definite values on undefined 2018-05-07 14:35:59 +02:00
Kasper Rynning-Tønnesen
ee6454d626 Moved hashlink test in embed 2018-05-07 14:31:42 +02:00
Kasper Rynning-Tønnesen
22b1e81cba Added a log to test embedded player 2018-05-07 14:28:34 +02:00
Kasper Rynning-Tønnesen
c7a75f2f72 Improvements to embedded player 2018-05-07 14:25:13 +02:00
Kasper Rynning-Tønnesen
1f921c3c34 Fixed issue where empty results would prevent search results from showing up 2018-05-07 13:48:19 +02:00
Kasper Rynning-Tønnesen
1c987514b3 Fixed issue with find in list function 2018-05-07 11:48:17 +02:00
Kasper Rynning-Tønnesen
ca2e73b00b Not removing toasts anymore until materializecss fixes issue that comes with it 2018-05-07 11:43:20 +02:00
Kasper Rynning-Tønnesen
b84ee96907 Small fix for coll/channel issue 2018-05-07 11:04:51 +02:00
Kasper Rynning-Tønnesen
b886878c43 Fixed stuttering issues on leaving and entering channel 2018-05-06 13:02:19 +02:00
Kasper Rynning-Tønnesen
fe01bcbe29 Stopping soundcloud player when navigating to frontpage from channel 2018-05-06 12:44:54 +02:00
Kasper Rynning-Tønnesen
3d1ec18cbd Visual fixes for search and fetchsuggestions fixesE 2018-05-06 12:16:08 +02:00
Kasper Rynning-Tønnesen
0d1c3139cb Removing player correctly on closing player from frontpage 2018-05-05 21:57:35 +02:00
Kasper Rynning-Tønnesen
723e163e80 Fixed small issues with client and navigating to a channel with soundcloud songs 2018-05-05 13:47:15 +02:00
Kasper Rynning-Tønnesen
8a64fc816a Fixes for chromecasting and embedded player 2018-05-05 13:05:49 +02:00
Kasper Rynning-Tønnesen
d4e3a8afde Empty_clear variable 2018-05-04 22:54:03 +02:00
Kasper Rynning-Tønnesen
05422252c7 Forgot to remove SC as a variable locally 2018-05-04 22:51:56 +02:00
Kasper Rynning-Tønnesen
658096b663 Fixed loading issues with soundcloud player 2018-05-04 22:49:41 +02:00
Kasper Rynning-Tønnesen
1c5b2ad3df Updated adminpanel to be able to pin a list with fewer elements generally also 2018-05-04 22:40:19 +02:00
Kasper Rynning-Tønnesen
ee3f178333 Updated adminpanel to be able to pin a list with fewer elements 2018-05-04 22:35:26 +02:00
Kasper Rynning-Tønnesen
588abcea2a Fix for crash on first song in channel is from soundcloud, and uglifying css with gulp again 2018-05-04 22:32:53 +02:00
Kasper Rynning-Tønnesen
25349ff6de Merge pull request #344 from zoff-music/feature/soundcloud-player
Fixes for suggested-showing of soundcloud objects
2018-05-04 22:26:31 +02:00
Kasper Rynning-Tønnesen
d9283a33b5 Fixes for suggested-showing of soundcloud objects 2018-05-04 22:25:43 +02:00
Kasper Rynning-Tønnesen
f9b56858fe Merge pull request #343 from zoff-music/feature/soundcloud-player
Fix for suggestions not appearing
2018-05-04 22:07:16 +02:00
Kasper Rynning-Tønnesen
dfe37df77c Fix for suggestions not appearing 2018-05-04 22:06:41 +02:00
Kasper Rynning-Tønnesen
2531f7caef Merge pull request #342 from zoff-music/feature/soundcloud-player
Feature/soundcloud player
2018-05-04 21:55:57 +02:00
Kasper Rynning-Tønnesen
f5bdaadff5 Updated version 2018-05-04 21:55:07 +02:00
Kasper Rynning-Tønnesen
2a4b7380e4 Better handling for frontpage-lists thumbnails 2018-05-04 21:44:57 +02:00
Kasper Rynning-Tønnesen
54a42548cf Cleaned up logs 2018-05-04 21:19:10 +02:00
Kasper Rynning-Tønnesen
1a170c6509 API now sending source and thumbnail 2018-05-04 21:05:34 +02:00
Kasper Rynning-Tønnesen
2c449e628d Added support for info from soundcloud on next_song info 2018-05-04 20:50:26 +02:00
Kasper Rynning-Tønnesen
6e4f844fea Added btc image 2018-05-04 17:38:08 +02:00
Kasper Rynning-Tønnesen
829c31b268 Sending source of video to chromecast 2018-05-04 17:21:18 +02:00
Kasper Rynning-Tønnesen
fc7966a008 Fixed issues with embedded player 2018-05-04 17:15:04 +02:00
Kasper Rynning-Tønnesen
3c87a148e1 Publisher and soundcloud attribute, streamer
- More attribute to publisher and soundcloud
- Started using the streamer api instead of widget api
2018-05-04 16:21:47 +02:00
Kasper Rynning-Tønnesen
06fb8d7046 Added buy/artist buttons when playing from soundcloud 2018-05-04 14:53:34 +02:00
Kasper Rynning-Tønnesen
3e1473caf8 Exporting of soundcloud implementation
- Fixed play/pause issue on stopping and playing the player
2018-05-04 14:40:02 +02:00
Kasper Rynning-Tønnesen
78be2aa820 Updated README's and other files to include SoundCloud mentions 2018-05-03 19:46:10 +02:00
Kasper Rynning-Tønnesen
2df793abb1 Updated RESTApi README 2018-05-03 19:36:53 +02:00
Kasper Rynning-Tønnesen
d6b7301464 Close player on frontpage now works with removing soundcloud 2018-05-03 19:34:33 +02:00
Kasper Rynning-Tønnesen
9442a2093b Fixed issues with window-history and soundcloud.load function 2018-05-03 19:31:31 +02:00
Kasper Rynning-Tønnesen
a095e23db0 Fixed stuttering on load from soundcloud 2018-05-03 16:50:27 +02:00
Kasper Rynning-Tønnesen
00e4f70c36 Upped performance of load somewhat for channel-load 2018-05-03 16:40:49 +02:00
Kasper Rynning-Tønnesen
3b1a87f14d Embedded version
- Embedded version now working with soundcloud-player
2018-05-03 15:45:34 +02:00
Kasper Rynning-Tønnesen
7d9873efd8 Start-end event updated
- Visual fixes
- Set start-time and end-time for soundcloud player working
2018-05-03 15:32:42 +02:00
Kasper Rynning-Tønnesen
2e404e6a61 Prettier soundcloud results and search-tabs 2018-05-03 14:30:49 +02:00
Kasper Rynning-Tønnesen
9b1e91783e Soundcloud-player + soundcloud-search added 2018-05-03 14:27:54 +02:00
80 changed files with 32419 additions and 22443 deletions

2
.gitignore vendored
View File

@@ -5,6 +5,8 @@ server/config/mongo_config.js
server/config/cert_config.js
server/config/recaptcha.js
server/config/analytics.js
server/config/google.js
server/config/allowed_api.js
server/public/assets/dist/maps/
server/public/assets/dist/callback.min.js
server/public/assets/dist/token.min.js

View File

@@ -1,7 +1,9 @@
Zoff
====
Zoff (pronounced __søff__) is a shared (free) YouTube and SoundCloud based radio service, built upon the YouTube API, and SoundCloud API, with integrated casting with Chromecast.
Zoff (pronounced __søff__) is a shared (free) YouTube and SoundCloud based radio service, built upon the YouTube API, and SoundCloud API, with integrated casting with Chromecast.
Zoff supports importing YouTube, SoundCloud and Spotify playlists, and has functionality that (tries to) export to YouTube, SoundCloud and Spotify.
<a href="https://zoff.me"><img height="80" src="https://puu.sh/BlSwW/57061de17b.png"></a><a class="android-image-link" href="https://play.google.com/store/apps/details?id=zoff.me.zoff&amp;hl=no&amp;pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1"><img alt="Get it on Google Play" height="65" src="https://puu.sh/BcWup/f560259c3f.png"></a>
<a style="padding-bottom:20px;" class="apple-image-link" href="https://itunes.apple.com/us/app/zoff/id1402037061?ls=1&amp;mt=8"><img height="65" alt="Get it on the AppStore" src="https://puu.sh/BcWvt/09002407c3.png"></a>
@@ -32,8 +34,6 @@ in ```/server/config```. There are ```*.example.js``` files for all the ones men
If you want to use Google Analytics, have a look at ```analytics.example.js``` in ```server/config/```.
If you have run the server before the table-structures where added, please run ```node server/apps/rewrite.js```. This will fix any crashes that occurs because of faulty document-collectionnames due to moving channel-settings to a separate collection.
Use ```$ npm start``` to start the server. (Alternative you can use the ```pm2.json``` in the project-root, if you prefer pm2 for running the apps.)
More info in <a href="https://github.com/zoff-music/zoff/blob/master/server/README.md">server/ README</a>
@@ -54,12 +54,18 @@ The team can be reached on <a href="mailto:contact@zoff.me?Subject=Contact%20Zof
![Channel desktop](https://puu.sh/xCHXj/3f7d826329.png)
![Channel settings](https://puu.sh/BCii4/f6594fc481.png)
![Channel join](https://puu.sh/zf1Ap/16587c0749.png)
![Channel search desktop](https://puu.sh/AhKTR/c1e6b5d8d2.png)
![Channel host mode desktop](https://puu.sh/AAGrK/953d11b2a7.png)
### Embedded player:
![embedded](https://puu.sh/BCQOs/9393bc5d09.png)
### Screenshots of the mobile version:
<div style="text-align:center;">

View File

@@ -1,114 +1,184 @@
var gulp = require('gulp'),
gutil = require('gulp-util'),
uglify = require('gulp-uglify'),
//sourcemaps = require('gulp-sourcemaps'),
concat = require('gulp-concat'),
cssnano = require('gulp-cssnano');
var gulp = require("gulp"),
uglify = require("gulp-uglify"),
//sourcemaps = require('gulp-sourcemaps'),
concat = require("gulp-concat"),
cleanCSS = require("gulp-clean-css");
gulp.task('css', function() {
return gulp.src('server/public/assets/css/style.css')
.pipe(cssnano({
preset: ['default', {
discardComments: {
removeAll: true,
},
}]
}))
.pipe(gulp.dest('server/public/assets/dist'));
gulp.task("css", function() {
return gulp
.src([
"server/public/assets/css/style.css",
"server/public/assets/css/globals.css",
"server/public/assets/css/animations.css",
"server/public/assets/css/mobile.css"
])
.pipe(concat("style.css"))
.pipe(cleanCSS({ compatibility: "ie8" }))
.pipe(gulp.dest("server/public/assets/dist"));
});
gulp.task('css-embed', function() {
return gulp.src('server/public/assets/css/embed.css')
.pipe(cssnano({
preset: ['default', {
discardComments: {
removeAll: true,
},
}]
}))
.pipe(gulp.dest('server/public/assets/dist'));
gulp.task("css-embed", function() {
return gulp
.src("server/public/assets/css/embed.css")
.pipe(cleanCSS({ compatibility: "ie8" }))
.pipe(gulp.dest("server/public/assets/dist"));
});
gulp.task('js', function () {
return gulp.src(['server/VERSION.js', 'server/config/api_key.js', 'server/public/assets/js/*.js', '!server/public/assets/js/embed*', '!server/public/assets/js/token*', '!server/public/assets/js/remotecontroller.js', '!server/public/assets/js/callback.js'])
//.pipe(sourcemaps.init())
.pipe(concat('main.min.js'))
.pipe(uglify({
mangle: true,
compress: true,
enclose: true,
}))
//.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest('server/public/assets/dist'));
gulp.task("js", function() {
return (
gulp
.src([
"server/VERSION.js",
"server/config/api_key.js",
"server/public/assets/js/*.js",
"!server/public/assets/js/embed*",
"!server/public/assets/js/token*",
"!server/public/assets/js/remotecontroller.js",
"!server/public/assets/js/callback.js"
])
//.pipe(sourcemaps.init())
.pipe(concat("main.min.js"))
.pipe(
uglify({
mangle: true,
compress: true,
enclose: true
})
)
//.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest("server/public/assets/dist"))
);
});
gulp.task('embed', function () {
return gulp.src(['server/VERSION.js', 'server/config/api_key.js', 'server/public/assets/js/player.js', 'server/public/assets/js/functions.js', 'server/public/assets/js/helpers.js', 'server/public/assets/js/playercontrols.js', 'server/public/assets/js/list.js', 'server/public/assets/js/embed.js', '!server/public/assets/js/frontpage*', '!server/public/assets/js/remotecontroller.js', 'server/public/assets/js/hostcontroller.js'])
//.pipe(sourcemaps.init())
.pipe(concat('embed.min.js'))
.pipe(uglify({
mangle: true,
compress: true,
enclose: true
}))
//.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest('server/public/assets/dist'));
gulp.task("embed", function() {
return (
gulp
.src([
"server/VERSION.js",
"server/config/api_key.js",
"server/public/assets/js/player.js",
"server/public/assets/js/functions.js",
"server/public/assets/js/helpers.js",
"server/public/assets/js/playercontrols.js",
"server/public/assets/js/list.js",
"server/public/assets/js/embed.js",
"!server/public/assets/js/frontpage*",
"!server/public/assets/js/remotecontroller.js",
"server/public/assets/js/hostcontroller.js"
])
//.pipe(sourcemaps.init())
.pipe(concat("embed.min.js"))
.pipe(
uglify({
mangle: true,
compress: true,
enclose: true
})
)
//.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest("server/public/assets/dist"))
);
});
gulp.task('token', function() {
return gulp.src(['server/public/assets/js/token*', 'server/public/assets/js/helpers.js'])
//.pipe(sourcemaps.init())
.pipe(concat('token.min.js'))
.pipe(uglify({
mangle: true,
compress: true,
enclose: true
}))
//.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest('server/public/assets/dist'));
})
gulp.task('callback', function () {
return gulp.src(['server/VERSION.js', 'server/config/api_key.js', 'server/public/assets/js/callback.js'])
//.pipe(sourcemaps.init())
.pipe(concat('callback.min.js'))
.pipe(uglify({
mangle: true,
compress: true,
enclose: true
}))
//.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest('server/public/assets/dist'));
gulp.task("token", function() {
return (
gulp
.src([
"server/public/assets/js/token*",
"server/public/assets/js/helpers.js"
])
//.pipe(sourcemaps.init())
.pipe(concat("token.min.js"))
.pipe(
uglify({
mangle: true,
compress: true,
enclose: true
})
)
//.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest("server/public/assets/dist"))
);
});
gulp.task('build', function() {
return gulp.run(['css', 'css-embed', 'js', 'embed', 'remotecontroller', 'callback', 'token']);
})
gulp.task('remotecontroller', function () {
return gulp.src(['server/VERSION.js', 'server/config/api_key.js', 'server/public/assets/js/remotecontroller.js', 'server/public/assets/js/helpers.js'])
////.pipe(sourcemaps.init())
.pipe(concat('remote.min.js'))
.pipe(uglify({
mangle: true,
compress: true,
enclose: true
}))
//.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest('server/public/assets/dist'));
gulp.task("callback", function() {
return (
gulp
.src([
"server/VERSION.js",
"server/config/api_key.js",
"server/public/assets/js/callback.js"
])
//.pipe(sourcemaps.init())
.pipe(concat("callback.min.js"))
.pipe(
uglify({
mangle: true,
compress: true,
enclose: true
})
)
//.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest("server/public/assets/dist"))
);
});
gulp.task('default', function(){
gulp.watch(['server/VERSION.js', 'server/public/assets/js/*.js'], ['js']);
gulp.watch(['server/public/assets/css/*.css'], ['css']);
gulp.watch(['server/public/assets/css/*.css'], ['css-embed']);
gulp.watch(['server/public/assets/js/token*.js', 'server/public/assets/js/helpers.js'], ['token']);
gulp.watch(['server/VERSION.js', 'server/public/assets/js/*.js'], ['embed']);
gulp.watch(['server/VERSION.js', 'server/public/assets/js/callback.js', 'server/public/assets/js/helpers.js'], ['callback']);
//gulp.watch('server/public/assets/js/*.js', ['nochan']);
gulp.watch(['server/VERSION.js', 'server/public/assets/js/remotecontroller.js'], ['remotecontroller']);
gulp.task("build", done => {
gulp.series(
"css",
"css-embed",
"js",
"embed",
"remotecontroller",
"callback",
"token"
)();
done();
});
gulp.task("remotecontroller", function() {
return (
gulp
.src([
"server/VERSION.js",
"server/config/api_key.js",
"server/public/assets/js/remotecontroller.js",
"server/public/assets/js/helpers.js"
])
////.pipe(sourcemaps.init())
.pipe(concat("remote.min.js"))
.pipe(
uglify({
mangle: true,
compress: true,
enclose: true
})
)
//.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest("server/public/assets/dist"))
);
});
gulp.task("default", function() {
gulp.watch(["server/VERSION.js", "server/public/assets/js/*.js"], ["js"]);
gulp.watch(["server/public/assets/css/*.css"], ["css"]);
gulp.watch(["server/public/assets/css/*.css"], ["css-embed"]);
gulp.watch(
["server/public/assets/js/token*.js", "server/public/assets/js/helpers.js"],
["token"]
);
gulp.watch(["server/VERSION.js", "server/public/assets/js/*.js"], ["embed"]);
gulp.watch(
[
"server/VERSION.js",
"server/public/assets/js/callback.js",
"server/public/assets/js/helpers.js"
],
["callback"]
);
//gulp.watch('server/public/assets/js/*.js', ['nochan']);
gulp.watch(
["server/VERSION.js", "server/public/assets/js/remotecontroller.js"],
["remotecontroller"]
);
});

5646
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
"description": "Zoff, the shared YouTube based radio services",
"main": "server/app.js",
"scripts": {
"start": "npm install --only=dev && npm install && gulp build && node server/app.js",
"start": "npm install --only=dev && npm install && $(npm bin)/gulp build && node server/app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
@@ -20,42 +20,44 @@
"url": "https://github.com/zoff-music/zoff/issues"
},
"devDependencies": {
"gulp": "~3.9.0",
"gulp": "^4.0.0",
"gulp-concat": "^2.6.1",
"gulp-cssnano": "^2.1.3",
"gulp-uglify": "^3.0.1",
"gulp-util": "~3.0.6"
"gulp-uglify": "^3.0.2"
},
"homepage": "https://github.com/zoff-music/zoff#readme",
"dependencies": {
"bad-words": "^1.6.1",
"bad-words": "^1.6.5",
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.17.1",
"body-parser": "^1.18.3",
"color-thief-jimp": "^2.0.2",
"compression": "^1.7.3",
"cookie-parser": "^1.4.3",
"cors": "^2.8.4",
"express": "^4.16.3",
"express-handlebars": "^3.0.0",
"connect-mongo": "^2.0.3",
"cookie-parser": "^1.4.4",
"cors": "^2.8.5",
"express": "^4.16.4",
"express-handlebars": "^3.0.2",
"express-recaptcha": "^3.0.1",
"express-session": "^1.15.6",
"express-sessions": "^1.0.6",
"gulp-sourcemaps": "^2.6.4",
"feature-policy": "^0.2.0",
"gulp-clean-css": "^4.2.0",
"gulp-sourcemaps": "^2.6.5",
"gulp-uglify-es": "^1.0.4",
"helmet": "^3.12.0",
"helmet": "^3.16.0",
"jimp": "^0.2.28",
"mongodb": "^2.2.35",
"mongojs": "^2.5.0",
"mongoose": "^5.0.16",
"mongodb": "^2.2.36",
"mongojs": "^2.6.0",
"mongojs-paginate": "^1.2.0",
"mongoose": "^5.4.18",
"mpromise": "^0.5.5",
"nodemailer": "^4.6.4",
"nodemailer": "^4.7.0",
"passport": "^0.4.0",
"passport-local": "^1.0.0",
"redis": "^2.8.0",
"request": "^2.85.0",
"socket.io": "^2.1.0",
"referrer-policy": "^1.1.0",
"request": "^2.88.0",
"socket.io": "^2.2.0",
"socket.io-redis": "^5.2.0",
"sticky-session": "^1.1.2",
"uniqid": "^4.1.1"
"uniqid": "5.0.3"
}
}

View File

@@ -1,16 +1,19 @@
{
"apps" : [
{
"name" : "zoff",
"script" : "./server/app.js",
"watch" : true,
"ignore_watch": ["./node_modules", "./server/public/assets/images/thumbnails"],
},
{
"name" : "gulp",
"script" : "./gulpfile.js",
"watch" : true,
"ignore_watch": ["./node_modules", "./server/"],
}
]
"apps": [
{
"name": "zoff",
"script": "./server/app.js",
"watch": true,
"ignore_watch": [
"./node_modules",
"./server/public/assets/images/thumbnails"
]
},
{
"name": "gulp",
"script": "./gulpfile.js",
"watch": true,
"ignore_watch": ["./node_modules", "./server/"]
}
]
}

View File

@@ -1,5 +1,5 @@
VERSION = 6;
try {
module.exports = VERSION;
} catch(e) {}
module.exports = VERSION;
} catch (e) {}

View File

@@ -1,139 +1,155 @@
var cluster = require('cluster'),
net = require('net'),
path = require('path'),
//publicPath = path.join(__dirname, 'public'),
http = require('http'),
port = 8080,
//farmhash = require('farmhash'),
uniqid = require('uniqid'),
num_processes = require('os').cpus().length;
var cluster = require("cluster"),
net = require("net"),
path = require("path"),
//publicPath = path.join(__dirname, 'public'),
http = require("http"),
port = 8080,
//farmhash = require('farmhash'),
uniqid = require("uniqid"),
num_processes = require("os").cpus().length;
publicPath = path.join(__dirname, 'public');
publicPath = path.join(__dirname, "public");
pathThumbnails = __dirname;
try {
var redis = require("redis");
var client = redis.createClient({host: "localhost", port: 6379});
client.on("error", function (err) {
console.log("Couldn't connect to redis-server, assuming non-clustered run");
num_processes = 1;
startClustered(false);
client.quit();
});
client.on("connect", function() {
startClustered(true);
client.quit();
});
} catch(e) {
var redis = require("redis");
var client = redis.createClient({ host: "localhost", port: 6379 });
client.on("error", function(err) {
console.log("Couldn't connect to redis-server, assuming non-clustered run");
num_processes = 1;
startClustered(false);
startSingle(false, false);
client.quit();
});
client.on("connect", function() {
startClustered(true);
client.quit();
});
} catch (e) {
console.log("Couldn't connect to redis-server, assuming non-clustered run");
num_processes = 1;
startSingle(false, false);
}
function startClustered(redis_enabled) {
//Found https://stackoverflow.com/questions/40885592/use-node-js-cluster-with-socket-io-chat-application
if (cluster.isMaster) {
var workers = [];
var spawn = function(i) {
workers[i] = cluster.fork();
workers[i].on('exit', function(code, signal) {
console.log('respawning worker', i);
spawn(i);
});
};
for (var i = 0; i < num_processes; i++) {
spawn(i);
//Found https://stackoverflow.com/questions/40885592/use-node-js-cluster-with-socket-io-chat-application
if (cluster.isMaster) {
var workers = [];
var spawn = function(i) {
workers[i] = cluster.fork();
workers[i].on("exit", function(code, signal) {
if (code == 1) {
process.exit(1);
return;
}
console.log("respawning worker", i);
spawn(i);
});
};
var worker_index = function(ip, len) {
//console.log(ip);
var s = '';
if(ip == undefined) ip = uniqid.time();
for (var i = 0, _len = ip.length; i < _len; i++) {
if(!isNaN(ip[i])) {
s += ip[i];
}
}
return Number(s)%len;
//eturn farmhash.fingerprint32(ip) % len;
};
var server = net.createServer({ pauseOnConnect: true }, function(connection, a) {
var worker = workers[worker_index(connection.remoteAddress, num_processes)];
worker.send('sticky-session:connection', connection);
}).listen(port);
} else {
startSingle(true, redis_enabled);
for (var i = 0; i < num_processes; i++) {
spawn(i);
}
var worker_index = function(ip, len) {
//console.log(ip);
var s = "";
if (ip == undefined) ip = uniqid.time();
for (var i = 0, _len = ip.length; i < _len; i++) {
if (!isNaN(ip[i])) {
s += ip[i];
}
}
return Number(s) % len;
//eturn farmhash.fingerprint32(ip) % len;
};
var server = net
.createServer({ pauseOnConnect: true }, function(connection, a) {
var worker =
workers[worker_index(connection.remoteAddress, num_processes)];
worker.send("sticky-session:connection", connection);
})
.listen(port);
} else {
startSingle(true, redis_enabled);
}
}
function startSingle(clustered, redis_enabled) {
var server;
var client = require('./apps/client.js');
var server;
var client = require("./apps/client.js");
try {
var cert_config = require(path.join(
path.join(__dirname, "config"),
"cert_config.js"
));
var fs = require("fs");
var privateKey = fs.readFileSync(cert_config.privateKey).toString();
var certificate = fs.readFileSync(cert_config.certificate).toString();
var ca = fs.readFileSync(cert_config.ca).toString();
var credentials = {
key: privateKey,
cert: certificate,
ca: ca
};
var https = require("https");
server = https.Server(credentials, routingFunction);
} catch (err) {
console.log("Starting without https (probably on localhost)");
server = http.createServer(routingFunction);
}
if (clustered) {
server.listen(onListen);
} else {
server.listen(port, onListen);
}
var socketIO = client.socketIO;
if (redis_enabled) {
var redis = require("socket.io-redis");
try {
var cert_config = require(path.join(path.join(__dirname, 'config'), 'cert_config.js'));
var fs = require('fs');
var privateKey = fs.readFileSync(cert_config.privateKey).toString();
var certificate = fs.readFileSync(cert_config.certificate).toString();
var ca = fs.readFileSync(cert_config.ca).toString();
var credentials = {
key: privateKey,
cert: certificate,
ca: ca
};
var https = require('https');
server = https.Server(credentials, routingFunction);
} catch(err){
console.log("Starting without https (probably on localhost)");
server = http.createServer(routingFunction);
socketIO.adapter(redis({ host: "localhost", port: 6379 }));
} catch (e) {
console.log("No redis-server to connect to..");
}
}
socketIO.listen(server);
if(clustered) {
server.listen(onListen);
} else {
server.listen(port, onListen);
process.on("message", function(message, connection) {
if (message !== "sticky-session:connection") {
return;
}
var socketIO = client.socketIO;
if(redis_enabled) {
var redis = require('socket.io-redis');
try {
socketIO.adapter(redis({ host: 'localhost', port: 6379 }));
} catch(e) {
console.log("No redis-server to connect to..");
}
}
socketIO.listen(server);
process.on('message', function(message, connection) {
if (message !== 'sticky-session:connection') {
return;
}
server.emit('connection', connection);
connection.resume();
});
server.emit("connection", connection);
connection.resume();
});
}
function onListen() {
console.log("Started with pid [" + process.pid + "]");
console.log("Started with pid [" + process.pid + "]");
}
function routingFunction(req, res, next) {
var client = require('./apps/client.js');
var admin = require('./apps/admin.js');
try {
var url = req.headers['x-forwarded-host'] ? req.headers['x-forwarded-host'] : req.headers.host.split(":")[0];
var subdomain = req.headers['x-forwarded-host'] ? req.headers['x-forwarded-host'].split(".") : req.headers.host.split(":")[0].split(".");
var client = require("./apps/client.js");
var admin = require("./apps/admin.js");
try {
var url = req.headers["x-forwarded-host"]
? req.headers["x-forwarded-host"]
: req.headers.host.split(":")[0];
var subdomain = req.headers["x-forwarded-host"]
? req.headers["x-forwarded-host"].split(".")
: req.headers.host.split(":")[0].split(".");
if(subdomain.length > 1 && subdomain[0] == "admin") {
admin(req, res, next);
} else {
client(req, res, next);
}
} catch(e) {
res.status(500);
if (subdomain.length > 1 && subdomain[0] == "admin") {
admin(req, res, next);
} else {
client(req, res, next);
}
} catch (e) {
console.log("Bad request for " + req.headers.host + req.url, e);
res.statusCode = 500;
res.write("Bad request"); //write a response to the client
res.end(); //end the response
}
}

View File

@@ -1,45 +0,0 @@
path = require('path'),
pathThumbnails = __dirname;
db = require(pathThumbnails + '/../handlers/db.js');
var usual = [];
var settings = [];
db.getCollectionNames(function(err, docs) {
for(var i = 0; i < docs.length; i++) {
//console.log(docs[i] == "");
if(docs[i].indexOf("_settings") == -1 && docs[i].substring(0,1) != "." && docs[i].substring(docs[i].length - 1, docs[i].length) != ".") {
t(docs[i]);
}
}
/*for(var i = 0; i < docs.length; i++) {
if(docs[i].indexOf("_settings") > -1) {
settings.push(docs[0]);
} else {
usual.push(docs[0]);
}
//addType(docs[i]);
}
for(var i = 0; i < usual.length; i++) {
if(settings.indexOf(usual + "_settings") < 0) {
console.log(usual);
}
}*/
})
function t(docs) {
db.collection(docs).find({id: {$exists: true}}, function(e, _docs) {
if(_docs.length > 0) {
db.collection(docs).createIndex({id: 1}, {unique: true}, function(e,d){
console.log(docs);
});
}
})
}
function addType(name) {
if(name.indexOf("_settings") > -1) {
db.collection(name).update({views: {$exists: true}}, {$set: { id: "config" }}, {multi: true}, function(err, doc) {
console.log(name);
});
}
}

View File

@@ -1,219 +1,268 @@
var express = require('express');
var express = require("express");
var app = express();
const path = require('path');
const publicPath = path.join(__dirname + "", '../public');
var exphbs = require('express-handlebars');
const path = require("path");
const publicPath = path.join(__dirname + "", "../public");
var exphbs = require("express-handlebars");
var hbs = exphbs.create({
defaultLayout: publicPath + '/layouts/admin/main',
layoutsDir: publicPath + '/layouts',
partialsDir: publicPath + '/partials'
defaultLayout: publicPath + "/layouts/admin/main",
layoutsDir: publicPath + "/layouts",
partialsDir: publicPath + "/partials"
});
var passport = require('passport');
var mpromise = require('mpromise');
var LocalStrategy = require('passport-local').Strategy;
var mongoose = require('mongoose');
var mongo_db_cred = require(pathThumbnails + '/config/mongo_config.js');
var mongojs = require('mongojs');
var passport = require("passport");
var mpromise = require("mpromise");
var LocalStrategy = require("passport-local").Strategy;
var mongoose = require("mongoose");
var mongo_db_cred = require(pathThumbnails + "/config/mongo_config.js");
var mongojs = require("mongojs");
var db = mongojs(mongo_db_cred.config);
var token_db = mongojs("tokens");
var bodyParser = require('body-parser');
var session = require('express-session');
var api = require(pathThumbnails + '/routing/admin/api.js');
var bodyParser = require("body-parser");
var session = require("express-session");
var MongoStore = require("connect-mongo")(session);
var api = require(pathThumbnails + "/routing/admin/api.js");
var User = require(pathThumbnails + '/models/user.js');
var url = 'mongodb://' + mongo_db_cred.host + '/' + mongo_db_cred.users;
var compression = require("compression");
var User = require(pathThumbnails + "/models/user.js");
var url = "mongodb://" + mongo_db_cred.host + "/" + mongo_db_cred.users;
mongoose.connect(url);
app.engine("handlebars", hbs.engine);
app.set("view engine", "handlebars");
app.use(compression({ filter: shouldCompress }));
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
app.set('trust proxy', '127.0.0.1');
app.enable('view cache');
app.set('views', publicPath);
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(session({
secret: mongo_db_cred.secret,
resave: true,
saveUninitialized: true,
store: new (require('express-sessions'))({
storage: 'mongodb',
instance: mongoose,
host: mongo_db_cred.host,
port: 27017,
collection: 'sessions',
expire: mongo_db_cred.expire
function shouldCompress(req, res) {
if (req.headers["x-no-compression"]) {
// don't compress responses with this request header
return false;
}
// fallback to standard filter function
return compression.filter(req, res);
}
app.set("trust proxy", "127.0.0.1");
var bodyParser = require("body-parser");
var cookieParser = require("cookie-parser");
var referrerPolicy = require("referrer-policy");
var helmet = require("helmet");
var featurePolicy = require("feature-policy");
app.use(
featurePolicy({
features: {
fullscreen: ["*"],
//vibrate: ["'none'"],
payment: ["'none'"],
microphone: ["'none'"],
camera: ["'none'"],
speaker: ["*"],
syncXhr: ["'self'"]
//notifications: ["'self'"]
}
})
})); // session secret
);
app.use(
helmet({
frameguard: false
})
);
app.use(referrerPolicy({ policy: "origin-when-cross-origin" }));
app.enable("view cache");
app.set("views", publicPath);
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(
bodyParser.urlencoded({
extended: true
})
);
app.use(
session({
secret: mongo_db_cred.secret,
resave: true,
saveUninitialized: true,
store: new MongoStore({
url: url,
useNewUrlParser: true,
collection: "sessions",
ttl: mongo_db_cred.expire
})
})
); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
//app.use('/assets', express.static(publicPath + '/assets'));
passport.serializeUser(function(user, done) {
done(null, user.id);
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with username
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
passport.use(
"local-signup",
new LocalStrategy(
{
// by default, local strategy uses username and password, we will override with username
usernameField: "username",
passwordField: "password",
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// find a user whose username is the same as the forms username
// we are checking to see if the user trying to login already exists
var token = req.body.token;
token_db
.collection("tokens")
.find({ token: token }, function(err, docs) {
if (docs.length == 1) {
token_db
.collection("tokens")
.remove({ token: token }, function(err, docs) {
User.findOne({ username: username }, function(err, user) {
// if there are any errors, return the error
if (err) return done(err);
// find a user whose username is the same as the forms username
// we are checking to see if the user trying to login already exists
var token = req.body.token;
token_db.collection("tokens").find({token: token}, function(err, docs){
if(docs.length == 1){
token_db.collection("tokens").remove({token: token}, function(err, docs){
User.findOne({ 'username' : username }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that username
if (user) {
return done(null, false);
} else {
// if there is no user with that username
// create the user
var newUser = new User();
// check to see if theres already a user with that username
if (user) {
return done(null, false);
} else {
// set the user's local credentials
newUser.username = username;
newUser.password = newUser.generateHash(password);
// if there is no user with that username
// create the user
var newUser = new User();
// set the user's local credentials
newUser.username = username;
newUser.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
// save the user
newUser.save(function(err) {
if (err) throw err;
return done(null, newUser);
});
}
});
});
} else {
return done(null, false);
}
});
}
});
});
} else {
return done(null, false);
}
});
});
});
}));
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
}, function(req, username, password, done) { // callback with email and password from our form
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'username' : username }, function(err, user) {
// if there are any errors, return the error before anything else
if (err)
return done(err);
// if no user is found, return the message
if (!user)
return done(null, false); // req.flash is the way to set flashdata using connect-flash
// if the user is found but the password is wrong
if (!user.validPassword(password))
return done(null, false); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, user);
});
}));
app.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
app.post('/login', passport.authenticate('local-login', {
successRedirect : '/', // redirect to the secure profile section
failureRedirect : '/login#failed', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
app.use('/login', isLoggedInTryingToLogIn, function(req, res) {
var data = {
where_get: "not_authenticated"
};
res.render('layouts/admin/not_authenticated', data);
});
app.use('/signup', isLoggedInTryingToLogIn, function(req, res) {
var data = {
where_get: "not_authenticated"
};
res.render('layouts/admin/not_authenticated', data);
});
app.use('/', api);
app.use('/logout', function(req, res) {
req.logout();
res.redirect('/login');
});
app.use('/assets/admin/authenticated', function(req, res, next) {
if(!req.isAuthenticated()) {
res.sendStatus(403);
return;
}
)
);
passport.use(
"local-login",
new LocalStrategy(
{
// by default, local strategy uses username and password, we will override with email
usernameField: "username",
passwordField: "password",
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
// callback with email and password from our form
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ username: username }, function(err, user) {
// if there are any errors, return the error before anything else
if (err) return done(err);
// if no user is found, return the message
if (!user) return done(null, false); // req.flash is the way to set flashdata using connect-flash
// if the user is found but the password is wrong
if (!user.validPassword(password)) return done(null, false); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, user);
});
}
)
);
app.post(
"/signup",
passport.authenticate("local-signup", {
successRedirect: "/", // redirect to the secure profile section
failureRedirect: "/signup", // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
})
);
app.post(
"/login",
passport.authenticate("local-login", {
successRedirect: "/", // redirect to the secure profile section
failureRedirect: "/login#failed", // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
})
);
app.use("/login", isLoggedInTryingToLogIn, function(req, res) {
var data = {
where_get: "not_authenticated"
};
res.render("layouts/admin/not_authenticated", data);
});
app.use("/signup", isLoggedInTryingToLogIn, function(req, res) {
var data = {
where_get: "not_authenticated"
};
res.render("layouts/admin/not_authenticated", data);
});
app.use("/", api);
app.use("/logout", function(req, res) {
req.logout();
res.redirect("/login");
});
app.use("/assets/admin/authenticated", function(req, res, next) {
if (!req.isAuthenticated()) {
res.sendStatus(403);
return;
}
return next();
});
app.use("/assets", express.static(publicPath + "/assets"));
app.use("/", isLoggedIn, function(req, res) {
var data = {
where_get: "authenticated",
year: new Date().getYear() + 1900
};
res.render("layouts/admin/authenticated", data);
});
function isLoggedInTryingToLogIn(req, res, next) {
if (!req.isAuthenticated()) {
return next();
});
app.use('/assets', express.static(publicPath + '/assets'));
app.use('/', isLoggedIn, function(req, res) {
var data = {
where_get: "authenticated",
year: new Date().getYear()+1900,
};
res.render('layouts/admin/authenticated', data);
});
function isLoggedInTryingToLogIn(req, res, next){
if(!req.isAuthenticated()){
return next();
}
res.redirect("/");
}
res.redirect("/");
}
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/login');
if (req.isAuthenticated()) return next();
res.redirect("/login");
}
//app.listen(default_port);

View File

@@ -1,52 +1,54 @@
VERSION = require(pathThumbnails + '/VERSION.js');
VERSION = require(pathThumbnails + "/VERSION.js");
var secure = false;
var path = require('path');
var path = require("path");
try {
var cert_config = require(path.join(path.join(__dirname, '../config/'), 'cert_config.js'));
var fs = require('fs');
var privateKey = fs.readFileSync(cert_config.privateKey).toString();
var certificate = fs.readFileSync(cert_config.certificate).toString();
var ca = fs.readFileSync(cert_config.ca).toString();
var credentials = {
key: privateKey,
cert: certificate,
ca: ca
};
secure = true;
} catch(err){}
var cert_config = require(path.join(
path.join(__dirname, "../config/"),
"cert_config.js"
));
var fs = require("fs");
var privateKey = fs.readFileSync(cert_config.privateKey).toString();
var certificate = fs.readFileSync(cert_config.certificate).toString();
var ca = fs.readFileSync(cert_config.ca).toString();
var credentials = {
key: privateKey,
cert: certificate,
ca: ca
};
secure = true;
} catch (err) {}
var add = "";
var express = require('express');
var express = require("express");
var app = express();
var compression = require('compression');
var exphbs = require('express-handlebars');
var cors = require('cors');
var Functions = require(pathThumbnails + '/handlers/functions.js');
var compression = require("compression");
var exphbs = require("express-handlebars");
var cors = require("cors");
var Functions = require(pathThumbnails + "/handlers/functions.js");
var hbs = exphbs.create({
defaultLayout: publicPath + '/layouts/client/main',
layoutsDir: publicPath + '/layouts/client',
partialsDir: publicPath + '/partials',
helpers: {
if_equal: function(a, b, opts) {
if (a == b) {
return opts.fn(this)
} else {
return opts.inverse(this)
}
},
decodeString: function(s) {
if(s == undefined) return s;
return Functions.decodeChannelName(s);
}
defaultLayout: publicPath + "/layouts/client/main",
layoutsDir: publicPath + "/layouts/client",
partialsDir: publicPath + "/partials",
helpers: {
if_equal: function(a, b, opts) {
if (a == b) {
return opts.fn(this);
} else {
return opts.inverse(this);
}
},
decodeString: function(s) {
if (s == undefined) return s;
return Functions.decodeChannelName(s);
}
}
});
var uniqid = require('uniqid');
app.use(compression({filter: shouldCompress}))
var uniqid = require("uniqid");
app.use(compression({ filter: shouldCompress }));
function shouldCompress (req, res) {
if (req.headers['x-no-compression']) {
function shouldCompress(req, res) {
if (req.headers["x-no-compression"]) {
// don't compress responses with this request header
return false;
}
@@ -55,115 +57,151 @@ function shouldCompress (req, res) {
return compression.filter(req, res);
}
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
app.enable('view cache');
app.set('views', publicPath);
app.set('trust proxy', '127.0.0.1');
app.engine("handlebars", hbs.engine);
app.set("view engine", "handlebars");
app.enable("view cache");
app.set("views", publicPath);
app.set("trust proxy", "127.0.0.1");
var bodyParser = require('body-parser');
var bodyParser = require("body-parser");
var cookieParser = require("cookie-parser");
var helmet = require('helmet')
app.use(helmet({
frameguard: false
}));
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
var referrerPolicy = require("referrer-policy");
var helmet = require("helmet");
var featurePolicy = require("feature-policy");
app.use(
featurePolicy({
features: {
fullscreen: ["*"],
//vibrate: ["'none'"],
payment: ["'none'"],
microphone: ["'none'"],
camera: ["'none'"],
speaker: ["*"],
syncXhr: ["'self'"]
//notifications: ["'self'"]
}
})
);
app.use(
helmet({
frameguard: false
})
);
app.use(referrerPolicy({ policy: "origin-when-cross-origin" }));
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(
bodyParser.urlencoded({
// to support URL-encoded bodies
extended: true
})
);
app.use(cookieParser());
app.set('json spaces', 2);
//app.set('json spaces', 2);
io = require('socket.io')({
pingTimeout: 25000,
//path: '/zoff',
//"origins": ("https://zoff.me:443*,https://zoff.me:8080*,zoff.me:8080*,https://remote.zoff.me:443*,https://remote.zoff.me:8080*,https://fb.zoff.me:443*,https://fb.zoff.me:8080*,https://admin.zoff.me:443*,https://admin.zoff.me:8080*, http://localhost:8080*")});
io = require("socket.io")({
pingTimeout: 25000
//path: '/zoff',
//"origins": ("https://zoff.me:443*,https://zoff.me:8080*,zoff.me:8080*,https://remote.zoff.me:443*,https://remote.zoff.me:8080*,https://fb.zoff.me:443*,https://fb.zoff.me:8080*,https://admin.zoff.me:443*,https://admin.zoff.me:8080*, http://localhost:8080*")});
});
var socketIO = require(pathThumbnails +'/handlers/io.js');
var socketIO = require(pathThumbnails + "/handlers/io.js");
socketIO();
app.socketIO = io;
/* Globally needed "libraries" and files */
var Functions = require(pathThumbnails + '/handlers/functions.js');
var router = require(pathThumbnails + '/routing/client/router.js');
var api = require(pathThumbnails + '/routing/client/api.js');
var ico_router = require(pathThumbnails + '/routing/client/icons_routing.js');
var router = require(pathThumbnails + "/routing/client/router.js");
var api_file = require(pathThumbnails + "/routing/client/api.js");
var api = api_file.router;
api_file.sIO = app.socketIO;
var ico_router = require(pathThumbnails + "/routing/client/icons_routing.js");
app.get('/robots.txt', function (req, res) {
res.type('text/plain');
res.send("User-agent: *\nAllow: /$\nDisallow: /");
app.get("/robots.txt", function(req, res) {
res.type("text/plain");
res.send("User-agent: *\nAllow: /$\nDisallow: /");
});
app.use(function (req, res, next) {
var cookie = req.cookies._uI;
var skipElements = ["/_embed", "/assets/manifest.json", "/apple-touch-icon.png"];
if(skipElements.indexOf(req.originalUrl) > -1) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
} else {
if(req.originalUrl.split("/").length > 3) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
} else {
if (cookie === undefined) {
try {
//console.error((new Date), "originalUrl", req.originalUrl);
//console.error((new Date), "couldn't fetch cookie for some reason, maybe no cookie exists?", req.get('origin'), "couldn't fetch cookie for some reason, maybe no cookie exists?");
} catch(e) {
//console.error((new Date), "couldn't fetch origin");
}
var user_name = Functions.hash_pass(Functions.rndName(uniqid.time(), 15));
res.cookie('_uI', user_name, {
maxAge: 365 * 10000 * 3600000,
httpOnly: true,
secure: secure,
sameSite: true,
});
} else {
//process.stderr.write((new Date), "couldn't fetch cookie for some reason, maybe no cookie exists?", req, "couldn't fetch cookie for some reason, maybe no cookie exists?");
res.cookie('_uI', cookie, {
maxAge: 365 * 10000 * 3600000,
httpOnly: true,
secure: secure,
sameSite: true,
});
}
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
}
}
app.use(function(req, res, next) {
var cookie = req.cookies._uI;
var skipElements = [
"/_embed",
"/assets/manifest.json",
"/apple-touch-icon.png"
];
if (skipElements.indexOf(req.originalUrl) > -1) {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
} else {
if (req.originalUrl.split("/").length > 3) {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
} else {
if (cookie === undefined) {
try {
//console.error((new Date), "originalUrl", req.originalUrl);
//console.error((new Date), "couldn't fetch cookie for some reason, maybe no cookie exists?", req.get('origin'), "couldn't fetch cookie for some reason, maybe no cookie exists?");
} catch (e) {
//console.error((new Date), "couldn't fetch origin");
}
var user_name = Functions.hash_pass(
Functions.rndName(uniqid.time(), 15)
);
res.cookie("_uI", user_name, {
maxAge: 365 * 10000 * 3600000,
httpOnly: true,
secure: secure
//sameSite: true,
});
} else {
//process.stderr.write((new Date), "couldn't fetch cookie for some reason, maybe no cookie exists?", req, "couldn't fetch cookie for some reason, maybe no cookie exists?");
res.cookie("_uI", cookie, {
maxAge: 365 * 10000 * 3600000,
httpOnly: true,
secure: secure
//sameSite: true,
});
}
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
}
}
});
app.use('/service-worker.js', function(req, res) {
res.sendFile(publicPath + '/service-worker.js');
app.use("/service-worker.js", function(req, res) {
res.sendFile(publicPath + "/service-worker.js");
});
app.use('/', ico_router);
app.use('/', api);
app.use('/', cors(), router);
app.use("/", ico_router);
app.use("/", api);
app.use("/", cors(), router);
app.use('/assets/js', function(req, res, next) {
res.sendStatus(403);
return;
app.use("/assets/js", function(req, res, next) {
res.sendStatus(403);
return;
});
app.use('/assets/admin', function(req, res, next) {
res.sendStatus(403);
return;
app.use("/assets/admin", function(req, res, next) {
res.sendStatus(403);
return;
});
app.use('/assets', express.static(publicPath + '/assets'));
app.use("/assets", express.static(publicPath + "/assets"));
app.use(function (req, res, next) {
app.use(function(req, res, next) {
res.status(404);
res.redirect("/404");
})
});
module.exports = app;

View File

@@ -0,0 +1,74 @@
var path = require('path');
var publicPath = path.join(__dirname, 'public');
var pathThumbnail = __dirname;
pathThumbnails = __dirname + "/../";
var time_regex = /P((([0-9]*\.?[0-9]*)Y)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)W)?(([0-9]*\.?[0-9]*)D)?)?(T(([0-9]*\.?[0-9]*)H)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)S)?)?/;
try {
var keys = require(path.join(__dirname, '../config/api_key.js'));
var key = keys.youtube;
var soundcloudKey = keys.soundcloud;
} catch(e) {
console.log("Error - missing file");
console.log("Seems you forgot to create the file api_key.js in /server/config/. Have a look at api_key.example.js.");
process.exit(1);
}
var Search = require(pathThumbnail + '/../handlers/search.js');
var request = require('request');
var db = require(pathThumbnail + '/../handlers/db.js');
var currentList = 0;
var listNames = [];
db.getCollectionNames(function(e, d) {
for(var i = 0; i < d.length; i++) {
if(d[i].indexOf("_") < 0) {
if(d[i].length > 0) {
if(d[i].substring(0, 1) == "." || d[i].substring(d[i].length - 1) == ".") continue;
}
listNames.push(d[i]);
}
}
console.log("Number of lists is " + listNames.length);
/*for(var i = 0; i < listNames.length; i++) {
getListItems(d[i]);
if(i > 1000) return;
}*/
recursivifyListLooping(listNames, 0);
});
function filterFunction(el) {
return el != null &&
el != "" &&
el != undefined &&
el.trim() != ''
}
function recursivifyListLooping(listNames, i) {
if(i > listNames.length) {
console.log("Done");
return;
}
console.log("List " + i + " of " + listNames.length);
getListItems(listNames, 0, function() {
console.log("done");
});
}
function getListItems(arr, i, callback) {
console.log("List " + i + " of " + listNames.length + " - " + arr[i]);
if(i >= arr.length) {
if(typeof(callback) == "function") callback();
return;
}
try {
db.collection(arr[i]).find(function(e, d) {
if(d.length > 0) {
Search.get_genres_list_recursive(d, arr[i], function(){
getListItems(arr, i + 1, callback);
});
} else {
getListItems(arr, i + 1, callback);
}
});
} catch(e) {
getListItems(arr, i + 1, callback);
}
}

View File

@@ -1,23 +0,0 @@
path = require('path'),
pathThumbnails = __dirname;
db = require(pathThumbnails + '/../handlers/db.js');
db.getCollectionNames(function(err, docs) {
for(var i = 0; i < docs.length; i++) {
makeNewAndDelete(docs[i]);
}
})
function makeNewAndDelete(name) {
db.collection(name).find({views: {$exists: true}}, function(err, doc) {
if(doc.length == 0) {
} else if(doc.length == 1) {
db.collection(name + "_settings").insert(doc[0], function(err, result){
console.log("Result insert", result);
db.collection(name).remove({views: {$exists: true}}, function(err, result_del) {
console.log("Result delete", result_del);
});
});
}
});
}

View File

@@ -0,0 +1,3 @@
var key = [""];
module.exports = key;

View File

@@ -1,3 +0,0 @@
var analytics = "xxxx";
module.exports = analytics;

View File

@@ -1,8 +1,8 @@
var api_key = {
"youtube": "xxxx",
"soundcloud": "xx",
youtube: "xxxx",
soundcloud: "xx" // This can be excluded if you don't have a soundcloud key
};
try {
module.exports = api_key;
} catch(e) {}
module.exports = api_key;
} catch (e) {}

View File

@@ -0,0 +1,6 @@
var google = {
"analytics": "xxxx",
"adsense": "xxxx",
}
module.exports = google;

View File

@@ -0,0 +1,65 @@
var toShowConfig = {
addsongs: true,
adminpass: 1,
allvideos: 1,
frontpage: 1,
longsongs: 1,
removeplay: 1,
shuffle: 1,
skip: 1,
startTime: 1,
userpass: 1,
vote: 1,
toggleChat: { $ifNull: ["$toggleChat", true] },
strictSkip: { $ifNull: ["$strictSkip", false] },
strictSkipNumber: { $ifNull: ["$strictSkipNumber", 10] },
description: { $ifNull: ["$description", ""] },
thumbnail: { $ifNull: ["$thumbnail", ""] },
rules: { $ifNull: ["$rules", ""] },
_id: 0
};
var project_object = {
_id: 0,
id: 1,
added: 1,
now_playing: 1,
title: 1,
votes: 1,
start: 1,
duration: 1,
end: 1,
type: 1,
added_by: { $ifNull: ["$added_by", "Anonymous"] },
source: { $ifNull: ["$source", "youtube"] },
thumbnail: {
$ifNull: [
"$thumbnail",
{
$concat: ["https://img.youtube.com/vi/", "$id", "/mqdefault.jpg"]
}
]
},
tags: { $ifNull: ["$tags", []] }
};
var toShowChannel = {
start: 1,
end: 1,
added: 1,
id: 1,
title: 1,
votes: 1,
duration: 1,
type: 1,
_id: 0,
tags: 1,
now_playing: 1,
type: 1,
source: 1,
thumbnail: 1
};
module.exports.project_object = project_object;
module.exports.toShowConfig = toShowConfig;
module.exports.toShowChannel = toShowChannel;

File diff suppressed because it is too large Load Diff

View File

@@ -1,39 +1,84 @@
var path = require('path');
var path = require("path");
try {
var mongo_config = require(path.join(path.join(__dirname, '../config/'), 'mongo_config.js'));
} catch(e) {
console.log("Error - missing file");
console.log("Seems you forgot to create the file mongo_config.js in /server/config/. Have a look at mongo_config.example.js.");
process.exit();
var mongo_config = require(path.join(
path.join(__dirname, "../config/"),
"mongo_config.js"
));
} catch (e) {
console.log(
"(!) Missing file - /config/mongo_config.js. Have a look at /config/mongo_config.example.js. The server won't run without this existing."
);
process.exit(1);
}
var mongojs = require('mongojs');
var db = mongojs('mongodb://' + mongo_config.host + '/' + mongo_config.config);
var connected_db = mongojs('mongodb://' + mongo_config.host + '/user_credentials');
var mongojs = require("mongojs");
var db = mongojs("mongodb://" + mongo_config.host + "/" + mongo_config.config);
var connected_db = mongojs(
"mongodb://" + mongo_config.host + "/user_credentials"
);
var ObjectId = mongojs.ObjectId;
db.collection("chat_logs").createIndex({ "createdAt": 1 }, { expireAfterSeconds: 600 }, function(){});
db.collection("timeout_api").createIndex({ "createdAt": 1 }, { expireAfterSeconds: 5 }, function(){});
db.collection("api_links").createIndex({ "createdAt": 1 }, { expireAfterSeconds: 86400 }, function(){});
db.on('connected', function(err) {
console.log("connected");
db.collection("chat_logs").createIndex(
{ createdAt: 1 },
{ expireAfterSeconds: 600 },
function() {}
);
db.collection("timeout_api").createIndex(
{ createdAt: 1 },
{ expireAfterSeconds: 120 },
function() {}
);
db.collection("api_links").createIndex(
{ createdAt: 1 },
{ expireAfterSeconds: 86400 },
function() {}
);
db.on("connected", function(err) {
console.log("connected");
});
db.on('error',function(err) {
console.log("\n" + new Date().toString() + "\n Database error: ", err);
db.on("error", function(err) {
console.log("\n" + new Date().toString() + "\n Database error: ", err);
});
db.on('error',function(err) {
console.log("\n" + new Date().toString() + "\n Database error: ", err);
db.on("error", function(err) {
console.log("\n" + new Date().toString() + "\n Database error: ", err);
});
/* Resetting usernames, and connected users */
db.collection("unique_ids").update({"_id": "unique_ids"}, {$set: {unique_ids: []}}, {multi: true, upsert: true}, function(err, docs){});
db.collection("user_names").remove({"guid": {$exists: true}}, {multi: true, upsert: true}, function(err, docs){});
db.collection("user_names").update({"_id": "all_names"}, {$set: {names: []}}, {multi: true, upsert: true}, function(err, docs){});
db.collection("connected_users").update({users: {$exists: true}}, {$set: {users: []}}, {multi: true, upsert: true}, function(err, docs){});
db.collection("connected_users").update({"_id": "total_users"}, {$set: {total_users: []}}, {multi: true, upsert: true}, function(err, docs) {});
db.collection("frontpage_lists").update({viewers: {$ne: 0}}, {$set: {"viewers": 0}}, {multi: true, upsert: true}, function(err, docs) {});
db.collection("unique_ids").update(
{ _id: "unique_ids" },
{ $set: { unique_ids: [] } },
{ multi: true, upsert: true },
function(err, docs) {}
);
db.collection("user_names").remove(
{ guid: { $exists: true } },
{ multi: true, upsert: true },
function(err, docs) {}
);
db.collection("user_names").update(
{ _id: "all_names" },
{ $set: { names: [] } },
{ multi: true, upsert: true },
function(err, docs) {}
);
db.collection("connected_users").update(
{ users: { $exists: true } },
{ $set: { users: [] } },
{ multi: true, upsert: true },
function(err, docs) {}
);
db.collection("connected_users").update(
{ _id: "total_users" },
{ $set: { total_users: [] } },
{ multi: true, upsert: true },
function(err, docs) {}
);
db.collection("frontpage_lists").update(
{ viewers: { $ne: 0 } },
{ $set: { viewers: 0 } },
{ multi: true, upsert: true },
function(err, docs) {}
);
module.exports = db;

View File

@@ -1,104 +1,143 @@
var Functions = require(pathThumbnails + '/handlers/functions.js');
var db = require(pathThumbnails + '/handlers/db.js');
var Functions = require(pathThumbnails + "/handlers/functions.js");
var db = require(pathThumbnails + "/handlers/db.js");
function frontpage_lists(msg, socket) {
if(msg == undefined || !msg.hasOwnProperty('version') || msg.version != VERSION || msg.version == undefined) {
var result = {
version: {
expected: VERSION,
got: msg.hasOwnProperty("version") ? msg.version : undefined,
}
};
socket.emit('update_required', result);
return;
}
if (
msg == undefined ||
!msg.hasOwnProperty("version") ||
msg.version != VERSION ||
msg.version == undefined
) {
var result = {
version: {
expected: VERSION,
got: msg.hasOwnProperty("version") ? msg.version : undefined
}
};
socket.emit("update_required", result);
return;
}
db.collection("frontpage_lists").find({frontpage:true}, function(err, docs){
db.collection("connected_users").find({"_id": "total_users"}, function(err, tot){
socket.compress(true).emit("playlists", {channels: docs, viewers: tot[0].total_users.length});
db.collection("frontpage_lists").find({ frontpage: true }, function(
err,
docs
) {
db.collection("connected_users").find({ _id: "total_users" }, function(
err,
tot
) {
socket
.compress(true)
.emit("playlists", {
channels: docs,
viewers: tot[0].total_users.length
});
});
});
}
function get_frontpage_lists(callback) {
var project_object = {
"_id": 1,
"count": 1,
"frontpage": 1,
"id": 1,
"title": 1,
"viewers": 1,
"accessed": 1,
"pinned": { $ifNull: [ "$pinned", 0 ] },
"description": {
$ifNull: [ {$cond: {
"if": {
"$or": [
{ "$eq": [ "$description", ""] },
{ "$eq": [ "$description", null] },
{ "$eq": [ "$description", undefined] }
]
},
then: "This list has no description",
else: "$description"
}}, "This list has no description"]
var project_object = {
_id: 1,
count: 1,
frontpage: 1,
id: 1,
title: 1,
viewers: 1,
accessed: 1,
pinned: { $ifNull: ["$pinned", 0] },
description: {
$ifNull: [
{
$cond: {
if: {
$or: [
{ $eq: ["$description", ""] },
{ $eq: ["$description", null] },
{ $eq: ["$description", undefined] }
]
},
then: "This list has no description",
else: "$description"
}
},
"thumbnail": {
$ifNull: [ {$cond: {
"if": {
"$or": [
{ "$eq": [ "$thumbnail", ""] },
{ "$eq": [ "$thumbnail", null] },
{ "$eq": [ "$thumbnail", undefined] }
]
},
then: {
$concat : [ "https://img.youtube.com/vi/", "$id", "/mqdefault.jpg"]
},
else: "$thumbnail"
}}, { $concat : [ "https://img.youtube.com/vi/", "$id", "/mqdefault.jpg"]}]
"This list has no description"
]
},
thumbnail: {
$ifNull: [
{
$cond: {
if: {
$or: [
{ $eq: ["$thumbnail", ""] },
{ $eq: ["$thumbnail", null] },
{ $eq: ["$thumbnail", undefined] }
]
},
then: {
$concat: ["https://img.youtube.com/vi/", "$id", "/mqdefault.jpg"]
},
else: "$thumbnail"
}
},
{ $concat: ["https://img.youtube.com/vi/", "$id", "/mqdefault.jpg"] }
]
}
};
db.collection("frontpage_lists").aggregate(
[
{
$match: {
frontpage: true,
count: { $gt: 3 }
}
};
db.collection("frontpage_lists").aggregate([
{
"$match": {
frontpage: true,
count: {$gt: 3},
}
},
{
"$project": project_object
},
{
"$sort" : {
"pinned": -1,
"viewers": -1,
"accessed": -1,
"count": -1,
"title": 1
}
},
], callback);
},
{
$project: project_object
},
{
$sort: {
pinned: -1,
viewers: -1,
accessed: -1,
count: -1,
title: 1
}
}
],
callback
);
}
function update_frontpage(coll, id, title, thumbnail, source, callback) {
//coll = coll.replace(/ /g,'');
db.collection("frontpage_lists").find({_id: coll}, function(e, doc) {
var updateObject = {
id: id,
title: title,
accessed: Functions.get_time()
};
if(doc.length > 0 && ((doc[0].thumbnail != "" && doc[0].thumbnail != undefined && (doc[0].thumbnail.indexOf("https://i1.sndcdn.com") > -1 || doc[0].thumbnail.indexOf("https://w1.sndcdn.com") > -1 || doc[0].thumbnail.indexOf("https://img.youtube.com") > -1)) || (doc[0].thumbnail == "" || doc[0].thumbnail == undefined))) {
updateObject.thumbnail = thumbnail;
if(thumbnail == undefined) updateObject.thumbnail = "";
}
db.collection("frontpage_lists").update({_id: coll}, {$set: updateObject
},{upsert: true}, function(err, returnDocs){
if(typeof(callback) == "function") callback();
});
});
//coll = coll.replace(/ /g,'');
db.collection("frontpage_lists").find({ _id: coll }, function(e, doc) {
var updateObject = {
id: id,
title: title,
accessed: Functions.get_time()
};
if (
doc.length > 0 &&
((doc[0].thumbnail != "" &&
doc[0].thumbnail != undefined &&
(doc[0].thumbnail.indexOf("https://i1.sndcdn.com") > -1 ||
doc[0].thumbnail.indexOf("https://w1.sndcdn.com") > -1 ||
doc[0].thumbnail.indexOf("https://img.youtube.com") > -1)) ||
(doc[0].thumbnail == "" || doc[0].thumbnail == undefined))
) {
updateObject.thumbnail = thumbnail;
if (thumbnail == undefined) updateObject.thumbnail = "";
}
db.collection("frontpage_lists").update(
{ _id: coll },
{ $set: updateObject },
{ upsert: true },
function(err, returnDocs) {
if (typeof callback == "function") callback();
}
);
});
}
module.exports.get_frontpage_lists = get_frontpage_lists;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,256 +1,397 @@
var Functions = require(pathThumbnails + '/handlers/functions.js');
var crypto = require('crypto');
var Filter = require('bad-words');
var filter = new Filter({ placeHolder: 'x'});
var Functions = require(pathThumbnails + "/handlers/functions.js");
var crypto = require("crypto");
var Filter = require("bad-words");
var filter = new Filter({ placeHolder: "x" });
/*var filter = {
clean: function(str) {
return str;
}
}*/
var db = require(pathThumbnails + '/handlers/db.js');
var projects = require(pathThumbnails + "/handlers/aggregates.js");
var db = require(pathThumbnails + "/handlers/db.js");
function password(inp, coll, guid, offline, socket) {
var sessionId = Functions.getSession(socket);
if(sessionId == "") sessionId = "empty";
if(inp !== undefined && inp !== null && inp !== "")
{
if(!inp.hasOwnProperty("password") || !inp.hasOwnProperty("channel") ||
typeof(inp.password) != "string" || typeof(inp.channel) != "string") {
var result = {
channel: {
expected: "string",
got: inp.hasOwnProperty("channel") ? typeof(inp.channel) : undefined,
},
password: {
expected: "password",
got: inp.hasOwnProperty("password") ? typeof(inp.password) : undefined,
},
};
socket.emit('update_required', result);
return;
var sessionId = Functions.getSession(socket);
if (sessionId == "") sessionId = "empty";
if (inp !== undefined && inp !== null && inp !== "") {
if (
!inp.hasOwnProperty("password") ||
!inp.hasOwnProperty("channel") ||
typeof inp.password != "string" ||
typeof inp.channel != "string"
) {
var result = {
channel: {
expected: "string",
got: inp.hasOwnProperty("channel") ? typeof inp.channel : undefined
},
password: {
expected: "password",
got: inp.hasOwnProperty("password") ? typeof inp.password : undefined
}
pw = inp.password;
try {
coll = inp.channel;
if(coll.length == 0) return;
coll = Functions.removeEmojis(coll).toLowerCase();
//coll = coll.replace(/_/g, "");
//coll = filter.clean(coll);
} catch(e) {
return;
}
//coll = coll.replace(/ /g,'');
uncrypted = pw;
pw = Functions.hash_pass(Functions.decrypt_string(pw), true);
Functions.check_inlist(coll, guid, socket, offline);
Functions.getSessionAdminUser(sessionId, coll, function(userpass, adminpass) {
db.collection(coll + "_settings").find(function(err, docs){
if(docs !== null && docs.length !== 0)
{
if(docs[0].adminpass === "" || docs[0].adminpass == Functions.hash_pass(pw))
{
Functions.setSessionAdminPass(sessionId, inp.password, coll, function() {
db.collection(coll + "_settings").update({ id: "config" }, {$set:{adminpass:Functions.hash_pass(pw)}}, function(err, docs){
if(adminpass != pw && adminpass != "") {
socket.emit("toast", "changedpass");
} else {
socket.emit("toast", "correctpass");
}
socket.emit("pw", true);
});
});
} else if(docs[0].adminpass === "" || docs[0].adminpass == Functions.hash_pass(Functions.hash_pass(Functions.decrypt_string(adminpass), true))) {
Functions.setSessionAdminPass(sessionId, inp.password, coll, function() {
db.collection(coll + "_settings").update({ id: "config" }, {$set:{adminpass:Functions.hash_pass(pw)}}, function(err, docs){
if(adminpass != pw) {
socket.emit("toast", "changedpass");
}
socket.emit("pw", true);
});
});
} else {
Functions.setSessionAdminPass(Functions.getSession(socket), "", coll, function() {
socket.emit("toast", "wrongpass");
socket.emit("pw", false);
});
}
}
});
});
} else {
var result = {
inp: {
expected: "string",
got: typeof(inpt)
},
};
socket.emit('update_required', result);
};
socket.emit("update_required", result);
return;
}
pw = inp.password;
try {
coll = inp.channel;
if (coll.length == 0) return;
coll = Functions.removeEmojis(coll).toLowerCase();
//coll = coll.replace(/_/g, "");
//coll = filter.clean(coll);
} catch (e) {
return;
}
//coll = coll.replace(/ /g,'');
uncrypted = pw;
pw = Functions.hash_pass(Functions.decrypt_string(pw), true);
Functions.check_inlist(coll, guid, socket, offline, undefined, "place 8");
Functions.getSessionAdminUser(sessionId, coll, function(
userpass,
adminpass
) {
adminpass = Functions.hash_pass(adminpass);
db.collection(coll + "_settings").find(function(err, docs) {
if (docs !== null && docs.length !== 0) {
if (
docs[0].adminpass === "" ||
docs[0].adminpass == Functions.hash_pass(pw)
) {
Functions.setSessionAdminPass(
sessionId,
inp.password,
coll,
function() {
db.collection(coll + "_settings").update(
{ id: "config" },
{ $set: { adminpass: Functions.hash_pass(pw) } },
function(err, docs) {
if (adminpass != pw && adminpass != "") {
socket.emit("toast", "changedpass");
} else {
socket.emit("toast", "correctpass");
}
socket.emit("pw", true);
}
);
}
);
} else if (
docs[0].adminpass === "" ||
docs[0].adminpass == adminpass
) {
Functions.setSessionAdminPass(
sessionId,
inp.password,
coll,
function() {
db.collection(coll + "_settings").update(
{ id: "config" },
{ $set: { adminpass: Functions.hash_pass(pw) } },
function(err, docs) {
if (adminpass != pw) {
socket.emit("toast", "changedpass");
}
socket.emit("pw", true);
}
);
}
);
} else {
Functions.setSessionAdminPass(
Functions.getSession(socket),
"",
coll,
function() {
socket.emit("toast", "wrongpass");
socket.emit("pw", false);
}
);
}
}
});
});
} else {
var result = {
inp: {
expected: "string",
got: typeof inpt
}
};
socket.emit("update_required", result);
}
}
function conf_function(params, coll, guid, offline, socket) {
if(params !== undefined && params !== null && params !== "")
{
if(coll !== undefined) {
try {
coll = params.channel;//.replace(/ /g,'');
if(coll.length == 0) return;
coll = Functions.removeEmojis(coll).toLowerCase();
//coll = coll.replace(/_/g, "");
if (params !== undefined && params !== null && params !== "") {
if (coll !== undefined) {
try {
coll = params.channel; //.replace(/ /g,'');
if (coll.length == 0) return;
coll = Functions.removeEmojis(coll).toLowerCase();
//coll = coll.replace(/_/g, "");
//coll = filter.clean(coll);
} catch(e) {
return;
}
}
if(coll == "" || coll == undefined || coll == null) {
socket.emit("update_required");
return;
}
Functions.check_inlist(coll, guid, socket, offline);
Functions.getSessionAdminUser(Functions.getSession(socket), coll, function(userpass, adminpass, gotten) {
if(gotten) {
params.adminpass = adminpass;
if(!params.userpass_changed) params.userpass = userpass;
}
if(!params.hasOwnProperty('voting') || !params.hasOwnProperty('addsongs') ||
!params.hasOwnProperty('longsongs') || !params.hasOwnProperty('frontpage') ||
!params.hasOwnProperty('allvideos') || !params.hasOwnProperty('removeplay') ||
!params.hasOwnProperty('adminpass') || !params.hasOwnProperty('skipping') ||
!params.hasOwnProperty('shuffling') || !params.hasOwnProperty('channel') ||
typeof(params.userpass) != "string" || typeof(params.adminpass) != "string" ||
typeof(params.voting) != "boolean" || typeof(params.addsongs) != "boolean" ||
typeof(params.longsongs) != "boolean" || typeof(params.frontpage) != "boolean" ||
typeof(params.allvideos) != "boolean" || typeof(params.removeplay) != "boolean" ||
typeof(params.skipping) != "boolean" || typeof(params.shuffling) != "boolean" ||
typeof(params.userpass_changed) != "boolean") {
var result = {
adminpass: {
expected: "string",
got: params.hasOwnProperty("adminpass") ? typeof(params.adminpass) : undefined,
},
userpass: {
expected: "string",
got: params.hasOwnProperty("userpass") ? typeof(params.userpass) : undefined,
},
vote: {
expected: "boolean",
got: params.hasOwnProperty("vote") ? typeof(params.vote) : undefined,
},
addsongs: {
expected: "boolean",
got: params.hasOwnProperty("addsongs") ? typeof(params.addsongs) : undefined,
},
longsongs: {
expected: "boolean",
got: params.hasOwnProperty("longsongs") ? typeof(params.longsongs) : undefined,
},
frontpage: {
expected: "boolean",
got: params.hasOwnProperty("frontpage") ? typeof(params.frontpage) : undefined,
},
skipping: {
expected: "boolean",
got: params.hasOwnProperty("skipping") ? typeof(params.skipping) : undefined,
},
shuffling: {
expected: "boolean",
got: params.hasOwnProperty("shuffling") ? typeof(params.shuffling) : undefined,
},
userpass_changed: {
expected: "boolean",
got: params.hasOwnProperty("userpass_changed") ? typeof(params.userpass_changed) : undefined,
}
};
socket.emit("update_required", result);
return;
}
var voting = params.voting;
var addsongs = params.addsongs;
var longsongs = params.longsongs;
var frontpage = params.frontpage;
var allvideos = params.allvideos;
var removeplay = params.removeplay;
var adminpass = params.adminpass;
var skipping = params.skipping;
var shuffling = params.shuffling;
var userpass = Functions.decrypt_string(params.userpass);
if((!params.userpass_changed && frontpage) || (params.userpass_changed && userpass == "")) {
userpass = "";
} else if(params.userpass_changed && userpass != "") {
frontpage = false;
}
var description = "";
var hash;
if(params.description) description = params.description;
if(adminpass !== "") {
hash = Functions.hash_pass(Functions.hash_pass(Functions.decrypt_string(adminpass), true));
} else {
hash = adminpass;
}
if(userpass != "") {
userpass = crypto.createHash('sha256').update(userpass).digest("base64");
}
db.collection(coll + "_settings").find({id: "config"}, function(err, docs){
if(docs !== null && docs.length !== 0 && (docs[0].adminpass === "" || docs[0].adminpass == hash)) {
var obj = {
addsongs:addsongs,
allvideos:allvideos,
frontpage:frontpage,
skip:skipping,
vote:voting,
removeplay:removeplay,
shuffle:shuffling,
longsongs:longsongs,
adminpass:hash,
desc: description,
};
if(params.userpass_changed) {
obj["userpass"] = userpass;
} else if (frontpage) {
obj["userpass"] = "";
}
db.collection(coll + "_settings").update({ id: "config" }, {
$set:obj
}, function(err, docs){
Functions.setSessionUserPass(Functions.getSession(socket), params.userpass, coll, function() {
db.collection(coll + "_settings").find(function(err, docs){
if(docs[0].adminpass !== "") docs[0].adminpass = true;
if(docs[0].hasOwnProperty("userpass") && docs[0].userpass != "") docs[0].userpass = true;
else docs[0].userpass = false;
io.to(coll).emit("conf", docs);
socket.emit("toast", "savedsettings");
db.collection("frontpage_lists").update({_id: coll}, {$set:{
frontpage:frontpage, accessed: Functions.get_time()}
},
{upsert:true}, function(err, docs){});
});
});
});
} else {
socket.emit("toast", "wrongpass");
}
});
});
} else {
var result = {
params: {
expected: "object",
got: typeof(params),
}
}
socket.emit('update_required', result);
//coll = filter.clean(coll);
} catch (e) {
return;
}
}
if (coll == "" || coll == undefined || coll == null) {
socket.emit("update_required");
return;
}
Functions.check_inlist(coll, guid, socket, offline, undefined, "place 9");
Functions.getSessionAdminUser(Functions.getSession(socket), coll, function(
userpass,
adminpass,
gotten
) {
if (gotten) {
params.adminpass = adminpass;
if (!params.userpass_changed) params.userpass = userpass;
}
if (
!params.hasOwnProperty("voting") ||
!params.hasOwnProperty("addsongs") ||
!params.hasOwnProperty("longsongs") ||
!params.hasOwnProperty("frontpage") ||
!params.hasOwnProperty("allvideos") ||
!params.hasOwnProperty("removeplay") ||
!params.hasOwnProperty("adminpass") ||
!params.hasOwnProperty("skipping") ||
!params.hasOwnProperty("shuffling") ||
!params.hasOwnProperty("channel") ||
typeof params.userpass != "string" ||
typeof params.adminpass != "string" ||
typeof params.voting != "boolean" ||
typeof params.addsongs != "boolean" ||
typeof params.longsongs != "boolean" ||
typeof params.frontpage != "boolean" ||
typeof params.allvideos != "boolean" ||
typeof params.removeplay != "boolean" ||
typeof params.skipping != "boolean" ||
typeof params.shuffling != "boolean" ||
typeof params.userpass_changed != "boolean"
) {
var result = {
adminpass: {
expected: "string",
got: params.hasOwnProperty("adminpass")
? typeof params.adminpass
: undefined
},
userpass: {
expected: "string",
got: params.hasOwnProperty("userpass")
? typeof params.userpass
: undefined
},
vote: {
expected: "boolean",
got: params.hasOwnProperty("vote") ? typeof params.vote : undefined
},
addsongs: {
expected: "boolean",
got: params.hasOwnProperty("addsongs")
? typeof params.addsongs
: undefined
},
longsongs: {
expected: "boolean",
got: params.hasOwnProperty("longsongs")
? typeof params.longsongs
: undefined
},
frontpage: {
expected: "boolean",
got: params.hasOwnProperty("frontpage")
? typeof params.frontpage
: undefined
},
skipping: {
expected: "boolean",
got: params.hasOwnProperty("skipping")
? typeof params.skipping
: undefined
},
shuffling: {
expected: "boolean",
got: params.hasOwnProperty("shuffling")
? typeof params.shuffling
: undefined
},
userpass_changed: {
expected: "boolean",
got: params.hasOwnProperty("userpass_changed")
? typeof params.userpass_changed
: undefined
}
};
socket.emit("update_required", result);
return;
}
var voting = params.voting;
var addsongs = params.addsongs;
var longsongs = params.longsongs;
var frontpage = params.frontpage;
var allvideos = params.allvideos;
var removeplay = params.removeplay;
var adminpass = params.adminpass;
var skipping = params.skipping;
var shuffling = params.shuffling;
var userpass = Functions.decrypt_string(params.userpass);
if (
(!params.userpass_changed && frontpage) ||
(params.userpass_changed && userpass == "")
) {
userpass = "";
} else if (params.userpass_changed && userpass != "") {
frontpage = false;
}
var description = "";
var hash;
if (params.description) description = params.description;
if (adminpass !== "" && !gotten) {
hash = Functions.hash_pass(
Functions.hash_pass(Functions.decrypt_string(adminpass), true)
);
} else if (adminpass !== "" && gotten) {
hash = Functions.hash_pass(adminpass);
} else {
hash = adminpass;
}
if (userpass != "") {
if (!params.userpass_changed && gotten) {
} else {
userpass = crypto
.createHash("sha256")
.update(userpass)
.digest("base64");
}
}
db.collection(coll + "_settings").find({ id: "config" }, function(
err,
docs
) {
if (
docs !== null &&
docs.length !== 0 &&
(docs[0].adminpass === "" || docs[0].adminpass == hash)
) {
var obj = {
addsongs: addsongs,
allvideos: allvideos,
frontpage: frontpage,
skip: skipping,
vote: voting,
removeplay: removeplay,
shuffle: shuffling,
longsongs: longsongs,
adminpass: hash,
desc: description
};
if (
params.hasOwnProperty("toggleChat") &&
docs[0].adminpass != "" &&
docs[0].adminpass != undefined &&
docs[0].adminpass == hash
) {
obj.toggleChat = params.toggleChat;
}
if (
params.hasOwnProperty("strictSkip") &&
docs[0].adminpass != "" &&
docs[0].adminpass != undefined &&
docs[0].adminpass == hash
) {
obj.strictSkip = params.strictSkip;
}
if (
params.hasOwnProperty("strictSkipNumber") &&
docs[0].adminpass != "" &&
docs[0].adminpass != undefined &&
docs[0].adminpass == hash
) {
try {
obj.strictSkipNumber = parseInt(params.strictSkipNumber);
} catch (e) {}
}
if (params.userpass_changed) {
obj["userpass"] = userpass;
} else if (frontpage) {
obj["userpass"] = "";
}
db.collection(coll + "_settings").update(
{ id: "config" },
{
$set: obj
},
function(err, docs) {
Functions.setSessionUserPass(
Functions.getSession(socket),
obj["userpass"],
coll,
function() {
db.collection(coll + "_settings").aggregate(
[
{
$match: {
id: "config"
}
},
{
$project: projects.toShowConfig
}
],
function(err, docs) {
if (docs[0].adminpass !== "") docs[0].adminpass = true;
if (
docs[0].hasOwnProperty("userpass") &&
docs[0].userpass != ""
)
docs[0].userpass = true;
else docs[0].userpass = false;
io.to(coll).emit("conf", docs);
socket.emit("toast", "savedsettings");
db.collection("frontpage_lists").update(
{ _id: coll },
{
$set: {
frontpage: frontpage,
accessed: Functions.get_time()
}
},
{ upsert: true },
function(err, docs) {}
);
}
);
}
);
}
);
} else {
socket.emit("toast", "wrongpass");
}
});
});
} else {
var result = {
params: {
expected: "object",
got: typeof params
}
};
socket.emit("update_required", result);
}
}
module.exports.password = password;

View File

@@ -1,39 +1,47 @@
var path = require('path');
var path = require("path");
function requested_change(type, string, channel) {
try {
//channel = channel.replace(/ /g,'');
var nodemailer = require('nodemailer');
var mailconfig = require(path.join(__dirname, '../config/mailconfig.js'));
try {
//channel = channel.replace(/ /g,'');
var nodemailer = require("nodemailer");
var mailconfig = require(path.join(__dirname, "../config/mailconfig.js"));
let transporter = nodemailer.createTransport(mailconfig);
let transporter = nodemailer.createTransport(mailconfig);
transporter.verify(function(error, success) {
if (error) {
return;
} else {
var message = "A " + type + " change was requested on <b>" + channel + "</b><br><br>New supposed value is: <br><br><b>" + string + "</b><br><br><br> \
transporter.verify(function(error, success) {
if (error) {
return;
} else {
var message =
"A " +
type +
" change was requested on <b>" +
channel +
"</b><br><br>New supposed value is: <br><br><b>" +
string +
"</b><br><br><br> \
Go to <a href='https://admin.zoff.me/'>https://admin.zoff.me/</a> to accept or decline the request.";
var msg = {
from: mailconfig.from,
to: mailconfig.notify_mail,
subject: 'ZOFF: Requested new ' + type,
text: message,
html: message,
}
transporter.sendMail(msg, (error, info) => {
if (error) {
transporter.close();
return;
}
transporter.close();
});
}
var msg = {
from: mailconfig.from,
to: mailconfig.notify_mail,
subject: "ZOFF: Requested new " + type,
text: message,
html: message
};
transporter.sendMail(msg, (error, info) => {
if (error) {
transporter.close();
return;
}
transporter.close();
});
} catch(e) {
console.log("Mail is not configured and wont work");
console.log("Seems you forgot to create a mailconfig.js in /server/config/. Have a look at the mailconfig.example.js.");
}
}
});
} catch (e) {
console.log(
"(!) Missing file - /config/mailconfig.js Have a look at /config/mailconfig.example.js. "
);
}
}
module.exports.requested_change = requested_change;

View File

@@ -1,167 +1,620 @@
var path = require('path');
var path = require("path");
var time_regex = /P((([0-9]*\.?[0-9]*)Y)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)W)?(([0-9]*\.?[0-9]*)D)?)?(T(([0-9]*\.?[0-9]*)H)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)S)?)?/;
try {
var keys = require(path.join(__dirname, '../config/api_key.js'));
var key = keys.youtube;
} catch(e) {
console.log("Error - missing file");
console.log("Seems you forgot to create the file api_key.js in /server/config/. Have a look at api_key.example.js.");
process.exit();
var keys = require(path.join(__dirname, "../config/api_key.js"));
var key = keys.youtube;
var soundcloudKey = keys.soundcloud;
} catch (e) {
console.log(
"(!) Missing file - /config/api_key.js Have a look at /config/api_key.example.js. The server won't run without this existing."
);
process.exit(1);
}
var request = require("request");
var db = require(pathThumbnails + "/handlers/db.js");
var countryCodes = ["US", "NO", "SE", "DK", "CA", "EU", "UK"];
function check_if_error_or_blocked(id, channel, errored, callback) {
if (!errored) {
callback(false);
return;
}
db.collection(channel).find({ id: id, now_playing: true }, function(
err,
song
) {
if (song.length == 0) {
callback(false);
return;
}
var song_info = song[0];
if (song_info.source != "soundcloud") {
request(
{
type: "GET",
url:
"https://www.googleapis.com/youtube/v3/videos?part=id,status,contentDetails&key=" +
key +
"&id=" +
song_info.id
},
function(error, response, body) {
try {
var resp = JSON.parse(body);
if (resp.pageInfo.totalResults == 0) {
callback(true);
return;
} else if (!resp.items[0].status.embeddable) {
callback(true);
return;
} else if (
resp.items[0].contentDetails.hasOwnProperty("licensedContent") &&
resp.items[0].contentDetails.licensedContent
) {
callback(true);
return;
} else if (
resp.items[0].contentDetails.hasOwnProperty(
"regionRestriction"
) &&
resp.items[0].contentDetails.regionRestriction.hasOwnProperty(
"blocked"
) &&
resp.items[0].contentDetails.regionRestriction.blocked.length > 0
) {
var any = resp.items[0].contentDetails.blocked.some(function(
element
) {
return countryCodes.indexOf(element) > -1;
});
if (any) {
callback(true);
return;
}
}
callback(false);
return;
} catch (e) {
callback(true);
return;
}
}
);
} else {
request(
{
type: "GET",
url:
"http://api.soundcloud.com/tracks/" +
song_info.id +
"?client_id=" +
soundcloudKey
},
function(error, response, body) {
try {
var resp = JSON.parse(body);
if (resp.sharing != "public" || resp.embeddable_by != "all") {
callback(true);
return;
}
callback(false);
return;
} catch (e) {
callback(true);
return;
}
}
);
}
});
}
function filterFunction(el) {
return el != null && el != "" && el != undefined && el.trim() != "";
}
function get_genres_soundcloud(song, channel) {
request(
"http://api.soundcloud.com/tracks/" +
song.id +
"?client_id=" +
soundcloudKey,
function(err, response, body) {
if (err) {
console.log("error start", err, song, "error end");
return;
}
try {
var object = JSON.parse(body);
if (
!object.hasOwnProperty("genre") ||
!object.hasOwnProperty("tag_list")
)
return;
var genre = object.genre + ",";
genre = genre
.toLowerCase()
.split(",")
.concat(object.tag_list.toLowerCase().split('"'));
genre = genre.filter(filterFunction);
db.collection(channel).update(
{ id: song.id },
{
$set: {
tags: genre
}
},
function(e, d) {}
);
} catch (e) {
console.log("errored 2", e);
}
}
);
}
function get_genres_list(list, channel) {
var youtube_array = "";
var i = 0;
try {
for (var i = 0; i < list.length; i++) {
if (!list[i].hasOwnProperty("id")) continue;
if (list[i].source == undefined || list[i].source == "youtube") {
youtube_array += list[i].id + ",";
} else if (
list[i].source != undefined &&
list[i].source == "soundcloud"
) {
get_genres_soundcloud(list[i], channel);
}
}
if (youtube_array.length > 0) {
if (youtube_array > 49) {
var subList = [];
for (var i = 0; i < youtube_array.length; i++) {
subList.push(youtube_array[i]);
if (subList.length > 49) {
get_genres_youtube(subList.join(","), channel);
subList = [];
}
}
get_genres_youtube(subList.join(","), channel);
subList = [];
} else {
get_genres_youtube(youtube_array, channel);
}
}
} catch (e) {
console.log("errored", e);
return;
}
}
function start_soundcloud_get(arr, channel, callback) {
get_genres_soundcloud_recursive(arr, channel, 0, callback);
}
function get_genres_soundcloud_recursive(arr, channel, i, callback) {
if (i >= arr.length) {
if (typeof callback == "function") callback();
return;
}
var song = arr[i];
request(
"http://api.soundcloud.com/tracks/" +
song.id +
"?client_id=" +
soundcloudKey,
function(err, response, body) {
if (err) {
console.log("error start", err, song, "error end");
get_genres_soundcloud_recursive(arr, channel, i + 1, callback);
return;
}
try {
var object = JSON.parse(body);
if (
!object.hasOwnProperty("genre") ||
!object.hasOwnProperty("tag_list")
) {
get_genres_soundcloud_recursive(arr, channel, i + 1, callback);
return;
}
var genre = object.genre + ",";
genre = genre
.toLowerCase()
.split(",")
.concat(object.tag_list.toLowerCase().split('"'));
genre = genre.filter(filterFunction);
db.collection(channel).update(
{ id: song.id },
{
$set: {
tags: genre
}
},
function(e, d) {
get_genres_soundcloud_recursive(arr, channel, i + 1, callback);
}
);
} catch (e) {
console.log("errored 2", e);
get_genres_soundcloud_recursive(arr, channel, i + 1, callback);
}
}
);
}
function get_genres_list_recursive(list, channel, callback) {
var youtube_array = [];
var soundcloud_array = [];
for (var i = 0; i < list.length; i++) {
if (!list[i].hasOwnProperty("id")) continue;
if (list[i].source == undefined || list[i].source == "youtube") {
youtube_array.push(list[i]);
} else if (list[i].source != undefined && list[i].source == "soundcloud") {
soundcloud_array.push(list[i]);
}
}
start_youtube_get(youtube_array, channel, function() {
start_soundcloud_get(soundcloud_array, channel, function() {
if (typeof callback == "function") callback();
});
});
}
function start_youtube_get(arr, channel, callback) {
get_genres_youtube_recursive(arr, channel, 0, callback);
}
function get_genres_youtube_recursive(arr, channel, i, callback) {
if (i >= arr.length) {
if (typeof callback == "function") callback();
return;
}
var ids = [];
for (var y = i; y < arr.length; y++) {
if (ids.length >= 48) {
break;
}
ids.push(arr[y].id);
}
request(
{
type: "GET",
url:
"https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id,topicDetails&key=" +
key +
"&id=" +
ids.join(",")
},
function(error, response, body) {
if (error) {
get_genres_youtube_recursive(arr, channel, i + ids.length, callback);
return;
}
var resp = JSON.parse(body);
if (!resp.hasOwnProperty("items")) {
get_genres_youtube_recursive(arr, channel, i + ids.length, callback);
return;
}
if (resp.items.length > 0) {
for (var z = 0; z < resp.items.length; z++) {
if (!resp.items[z].hasOwnProperty("topicDetails")) continue;
var genre = resp.items[z].topicDetails.topicCategories;
genre = genre.join(",");
genre = genre.replace(
new RegExp("https://en.wikipedia.org/wiki/", "g"),
""
);
genre = genre
.replace(/_/g, " ")
.toLowerCase()
.split(",");
genre = genre.filter(filterFunction);
//console.log(resp.items[i].id + " - ", genre);
db.collection(channel).update(
{ id: resp.items[z].id },
{
$set: {
tags: genre
}
},
function(e, d) {}
);
}
get_genres_youtube_recursive(arr, channel, i + ids.length, callback);
} else {
get_genres_youtube_recursive(arr, channel, i + ids.length, callback);
}
}
);
}
function get_genres_youtube(ids, channel) {
request(
{
type: "GET",
url:
"https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id,topicDetails&key=" +
key +
"&id=" +
ids
},
function(error, response, body) {
if (error) {
return;
}
var resp = JSON.parse(body);
if (!resp.hasOwnProperty("items")) {
return;
}
if (resp.items.length > 0) {
for (var i = 0; i < resp.items.length; i++) {
if (!resp.items[i].hasOwnProperty("topicDetails")) continue;
var genre = resp.items[i].topicDetails.topicCategories;
genre = genre.join(",");
genre = genre.replace(
new RegExp("https://en.wikipedia.org/wiki/", "g"),
""
);
genre = genre
.replace(/_/g, " ")
.toLowerCase()
.split(",");
genre = genre.filter(filterFunction);
//console.log(resp.items[i].id + " - ", genre);
db.collection(channel).update(
{ id: resp.items[i].id },
{
$set: {
tags: genre
}
},
function(e, d) {}
);
}
}
}
);
}
var request = require('request');
var db = require(pathThumbnails + '/handlers/db.js');
function get_correct_info(song_generated, channel, broadcast, callback) {
//channel = channel.replace(/ /g,'');
request({
type: "GET",
url: "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id&key="+key+"&id=" + song_generated.id,
}, function(error, response, body) {
try {
var resp = JSON.parse(body);
if(resp.items.length == 1) {
var duration = parseInt(durationToSeconds(resp.items[0].contentDetails.duration));
var title = resp.items[0].snippet.localized.title;
if(title != song_generated.title || duration < parseInt(song_generated.duration)) {
if(title != song_generated.title) {
song_generated.title = title;
}
if(duration < parseInt(song_generated.duration)) {
song_generated.duration = duration;
song_generated.start = 0;
song_generated.end = duration;
}
db.collection(channel).update({"id": song_generated.id}, {
$set: {
"duration": song_generated.duration,
"start": song_generated.start,
"end": song_generated.end,
"title": song_generated.title,
}
}, function(err, docs) {
if(broadcast && docs.nModified == 1) {
song_generated.new_id = song_generated.id;
//if(song_generated.type == "video")
if(typeof(callback) == "function") {
callback(song_generated, true);
} else {
io.to(channel).emit("channel", {type: "changed_values", value: song_generated});
}
} else {
if(typeof(callback) == "function") {
callback(song_generated, true);
}
}
});
} else {
if(typeof(callback) == "function") {
callback(song_generated, true);
}
//channel = channel.replace(/ /g,'');
request(
{
type: "GET",
url:
"https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id,topicDetails&key=" +
key +
"&id=" +
song_generated.id
},
function(error, response, body) {
try {
var resp = JSON.parse(body);
if (resp.items.length == 1) {
var duration = parseInt(
durationToSeconds(resp.items[0].contentDetails.duration)
);
var title = resp.items[0].snippet.localized.title;
var genre = resp.items[0].topicDetails.topicCategories;
genre = genre.join(",");
genre = genre.replace(
new RegExp("https://en.wikipedia.org/wiki/", "g"),
""
);
genre = genre
.replace(/_/g, " ")
.toLowerCase()
.split(",");
genre = genre.filter(filterFunction);
//console.log(genre + " - ", song_generated.id);
if (
title != song_generated.title ||
duration < parseInt(song_generated.duration)
) {
if (title != song_generated.title) {
song_generated.title = title;
}
if (duration < parseInt(song_generated.duration)) {
song_generated.duration = duration;
song_generated.start = 0;
song_generated.end = duration;
}
db.collection(channel).update(
{ id: song_generated.id },
{
$set: {
duration: song_generated.duration,
start: song_generated.start,
end: song_generated.end,
title: song_generated.title,
tags: genre
}
} else {
findSimilar(song_generated, channel, broadcast, callback)
}
} catch(e){
if(typeof(callback) == "function") {
callback({}, false);
}
},
function(err, docs) {
if (broadcast && docs.nModified == 1) {
song_generated.new_id = song_generated.id;
//if(song_generated.type == "video")
if (typeof callback == "function") {
callback(song_generated, true);
} else {
io.to(channel).emit("channel", {
type: "changed_values",
value: song_generated
});
}
} else {
if (typeof callback == "function") {
callback(song_generated, true);
}
}
}
);
} else {
db.collection(channel).update(
{ id: song_generated.id },
{
$set: {
tags: genre
}
},
function(e, d) {
if (typeof callback == "function") {
callback(song_generated, true);
}
}
);
}
} else {
findSimilar(song_generated, channel, broadcast, callback);
}
});
} catch (e) {
if (typeof callback == "function") {
callback({}, false);
}
}
}
);
}
function check_error_video(msg, channel) {
if(!msg.hasOwnProperty("id") || !msg.hasOwnProperty("title") ||
typeof(msg.id) != "string" || typeof(msg.title) != "string") {
var result = {
id: {
expected: "string",
got: msg.hasOwnProperty("id") ? typeof(msg.id) : undefined,
},
title: {
expected: "string",
got: msg.hasOwnProperty("title") ? typeof(msg.title) : undefined,
},
};
return;
}
if(msg.source == "soundcloud") return;
//channel = channel.replace(/ /g,'');
request({
type: "GET",
url: "https://www.googleapis.com/youtube/v3/videos?part=id&key="+key+"&id=" + msg.id,
}, function(error, response, body) {
try {
var resp = JSON.parse(body);
if(resp.pageInfo.totalResults == 0) {
findSimilar(msg, channel, true, undefined)
}
} catch(e){
console.log(msg.id, key, e, body);
if (
!msg.hasOwnProperty("id") ||
!msg.hasOwnProperty("title") ||
typeof msg.id != "string" ||
typeof msg.title != "string"
) {
var result = {
id: {
expected: "string",
got: msg.hasOwnProperty("id") ? typeof msg.id : undefined
},
title: {
expected: "string",
got: msg.hasOwnProperty("title") ? typeof msg.title : undefined
}
};
return;
}
if (msg.source == "soundcloud") return;
//channel = channel.replace(/ /g,'');
request(
{
type: "GET",
url:
"https://www.googleapis.com/youtube/v3/videos?part=id&key=" +
key +
"&id=" +
msg.id
},
function(error, response, body) {
try {
var resp = JSON.parse(body);
if (resp.pageInfo.totalResults == 0) {
findSimilar(msg, channel, true, undefined);
}
});
} catch (e) {
console.log(msg.id, key, e, body);
}
}
);
}
function findSimilar(msg, channel, broadcast, callback) {
//channel = channel.replace(/ /g,'');
var yt_url = "https://www.googleapis.com/youtube/v3/search?key="+key+"&videoEmbeddable=true&part=id&type=video&order=viewCount&safeSearch=none&maxResults=5&q=" + encodeURIComponent(msg.title);
request({
method: "GET",
url: yt_url,
}, function(error, response, body){
var resp = JSON.parse(body);
if(resp.items.length > 0) {
var vid_url = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id&key="+key+"&id=";
for(var i = 0; i < resp.items.length; i++) {
vid_url += resp.items[i].id.videoId + ",";
}
request({
type: "GET",
url: vid_url
}, function(error, response, body) {
var resp = JSON.parse(body);
var found = false;
var element = {};
for(var i = 0; i < resp.items.length; i++) {
if(similarity(resp.items[i].snippet.localized.title, msg.title) > 0.75) {
found = true;
element = {
title: resp.items[i].snippet.localized.title,
duration: parseInt(durationToSeconds(resp.items[i].contentDetails.duration)),
id: resp.items[i].id,
start: 0,
end: parseInt(durationToSeconds(resp.items[i].contentDetails.duration)),
}
break;
}
}
if(found) {
db.collection(channel).update({"id": msg.id}, {
$set: element
}, function(err, docs) {
if(docs && docs.hasOwnProperty("nModified") && docs.nModified == 1 && broadcast) {
element.new_id = element.id;
element.id = msg.id;
if(!callback) {
io.to(channel).emit("channel", {type: "changed_values", value: element});
}
}
if(typeof(callback) == "function") {
msg.title = element.title;
msg.id = element.id;
msg.duration = element.duration;
msg.start = element.start;
msg.end = element.end;
callback(msg, true);
}
});
} else if(typeof(callback) == "function") {
callback({}, false);
}
});
//channel = channel.replace(/ /g,'');
var yt_url =
"https://www.googleapis.com/youtube/v3/search?key=" +
key +
"&videoEmbeddable=true&part=id&type=video&order=viewCount&safeSearch=none&maxResults=5&q=" +
encodeURIComponent(msg.title);
request(
{
method: "GET",
url: yt_url
},
function(error, response, body) {
var resp = JSON.parse(body);
if (resp.items.length > 0) {
var vid_url =
"https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id&key=" +
key +
"&id=";
for (var i = 0; i < resp.items.length; i++) {
vid_url += resp.items[i].id.videoId + ",";
}
});
request(
{
type: "GET",
url: vid_url
},
function(error, response, body) {
var resp = JSON.parse(body);
var found = false;
var element = {};
for (var i = 0; i < resp.items.length; i++) {
if (
similarity(resp.items[i].snippet.localized.title, msg.title) >
0.75
) {
found = true;
element = {
title: resp.items[i].snippet.localized.title,
duration: parseInt(
durationToSeconds(resp.items[i].contentDetails.duration)
),
id: resp.items[i].id,
start: 0,
end: parseInt(
durationToSeconds(resp.items[i].contentDetails.duration)
)
};
break;
}
}
if (found) {
db.collection(channel).update(
{ id: msg.id },
{
$set: element
},
function(err, docs) {
if (
docs &&
docs.hasOwnProperty("nModified") &&
docs.nModified == 1 &&
broadcast
) {
element.new_id = element.id;
element.id = msg.id;
if (!callback) {
io.to(channel).emit("channel", {
type: "changed_values",
value: element
});
}
}
if (typeof callback == "function") {
msg.title = element.title;
msg.id = element.id;
msg.duration = element.duration;
msg.start = element.start;
msg.end = element.end;
callback(msg, true);
}
}
);
} else if (typeof callback == "function") {
callback({}, false);
}
}
);
}
}
);
}
function similarity(s1, s2) {
@@ -175,7 +628,9 @@ function similarity(s1, s2) {
if (longerLength == 0) {
return 1.0;
}
return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength);
return (
(longerLength - editDistance(longer, shorter)) / parseFloat(longerLength)
);
}
function editDistance(s1, s2) {
@@ -186,32 +641,34 @@ function editDistance(s1, s2) {
for (var i = 0; i <= s1.length; i++) {
var lastValue = i;
for (var j = 0; j <= s2.length; j++) {
if (i == 0)
costs[j] = j;
if (i == 0) costs[j] = j;
else {
if (j > 0) {
var newValue = costs[j - 1];
if (s1.charAt(i - 1) != s2.charAt(j - 1))
newValue = Math.min(Math.min(newValue, lastValue),
costs[j]) + 1;
newValue = Math.min(Math.min(newValue, lastValue), costs[j]) + 1;
costs[j - 1] = lastValue;
lastValue = newValue;
}
}
}
if (i > 0)
costs[s2.length] = lastValue;
if (i > 0) costs[s2.length] = lastValue;
}
return costs[s2.length];
}
function durationToSeconds(duration) {
var matches = duration.match(time_regex);
hours= parseInt(matches[12])||0;
minutes= parseInt(matches[14])||0;
seconds= parseInt(matches[16])||0;
return hours*60*60+minutes*60+seconds;
var matches = duration.match(time_regex);
hours = parseInt(matches[12]) || 0;
minutes = parseInt(matches[14]) || 0;
seconds = parseInt(matches[16]) || 0;
return hours * 60 * 60 + minutes * 60 + seconds;
}
module.exports.check_if_error_or_blocked = check_if_error_or_blocked;
module.exports.get_genres_list_recursive = get_genres_list_recursive;
module.exports.get_genres_soundcloud = get_genres_soundcloud;
module.exports.get_genres_youtube = get_genres_youtube;
module.exports.get_genres_list = get_genres_list;
module.exports.check_error_video = check_error_video;
module.exports.get_correct_info = get_correct_info;

View File

@@ -1,116 +1,284 @@
var Functions = require(pathThumbnails + '/handlers/functions.js');
var Notifications = require(pathThumbnails + '/handlers/notifications.js');
var crypto = require('crypto');
var db = require(pathThumbnails + '/handlers/db.js');
var Functions = require(pathThumbnails + "/handlers/functions.js");
var Notifications = require(pathThumbnails + "/handlers/notifications.js");
var crypto = require("crypto");
var db = require(pathThumbnails + "/handlers/db.js");
function thumbnail(msg, coll, guid, offline, socket) {
if(msg.thumbnail != undefined && msg.channel && msg.channel != undefined && Functions.isUrl(msg.thumbnail)){
if(typeof(msg.channel) != "string" || typeof(msg.thumbnail) != "string")
{
var result = {
channel: {
expected: "string",
got: msg.hasOwnProperty("channel") ? typeof(msg.channel) : undefined,
},
pass: {
expected: "string",
got: msg.hasOwnProperty("pass") ? typeof(msg.pass) : undefined,
},
thumbnail: {
expected: "string",
got: msg.hasOwnProperty("thumbnail") ? typeof(msg.thumbnail) : undefined,
},
adminpass: {
expected: "string",
got: msg.hasOwnProperty("adminpass") ? typeof(msg.adminpass) : undefined,
},
};
socket.emit("update_required", result);
return;
}
//coll = coll.replace(/ /g,'');
Functions.getSessionAdminUser(Functions.getSession(socket), coll, function(userpass, adminpass) {
if(userpass != "" || msg.userpass == undefined) {
msg.userpass = userpass;
}
if(adminpass != "" || msg.adminpass == undefined) {
msg.adminpass = adminpass;
}
if(msg.thumbnail != "") {
msg.thumbnail = msg.thumbnail.replace(/^https?\:\/\//i, "");
if(msg.thumbnail.substring(0,2) != "//") msg.thumbnail = "//" + msg.thumbnail;
}
var channel = msg.channel.toLowerCase();
var hash = Functions.hash_pass(Functions.hash_pass(Functions.decrypt_string(msg.adminpass),true));
db.collection(channel + "_settings").find({id: "config"}, function(err, docs){
if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (msg.hasOwnProperty('pass') && docs[0].userpass == crypto.createHash('sha256').update(Functions.decrypt_string(msg.pass)).digest("base64")))) {
if(docs !== null && docs.length !== 0 && docs[0].adminpass !== "" && docs[0].adminpass == hash){
db.collection("suggested_thumbnails").update({channel: channel}, {$set:{thumbnail: msg.thumbnail}}, {upsert:true}, function(err, docs){
Notifications.requested_change("thumbnail", msg.thumbnail, channel);
socket.emit("toast", "suggested_thumbnail");
});
}
} else {
socket.emit("auth_required");
}
});
});
} else {
socket.emit("toast", "thumbnail_denied");
if (
msg.thumbnail != undefined &&
msg.channel &&
msg.channel != undefined &&
Functions.isUrl(msg.thumbnail)
) {
if (typeof msg.channel != "string" || typeof msg.thumbnail != "string") {
var result = {
channel: {
expected: "string",
got: msg.hasOwnProperty("channel") ? typeof msg.channel : undefined
},
pass: {
expected: "string",
got: msg.hasOwnProperty("pass") ? typeof msg.pass : undefined
},
thumbnail: {
expected: "string",
got: msg.hasOwnProperty("thumbnail")
? typeof msg.thumbnail
: undefined
},
adminpass: {
expected: "string",
got: msg.hasOwnProperty("adminpass")
? typeof msg.adminpass
: undefined
}
};
socket.emit("update_required", result);
return;
}
//coll = coll.replace(/ /g,'');
Functions.getSessionAdminUser(Functions.getSession(socket), coll, function(
userpass,
adminpass
) {
if (userpass != "" || msg.pass == undefined) {
msg.pass = userpass;
} else if (msg.hasOwnProperty("pass")) {
msg.pass = crypto
.createHash("sha256")
.update(Functions.decrypt_string(msg.pass))
.digest("base64");
}
if (adminpass != "" || msg.adminpass == undefined) {
msg.adminpass = Functions.hash_pass(adminpass);
} else {
msg.adminpass = Functions.hash_pass(
Functions.hash_pass(Functions.decrypt_string(msg.adminpass), true)
);
}
if (msg.thumbnail != "") {
msg.thumbnail = msg.thumbnail.replace(/^https?\:\/\//i, "");
if (msg.thumbnail.substring(0, 2) != "//")
msg.thumbnail = "//" + msg.thumbnail;
}
var channel = msg.channel.toLowerCase();
var hash = msg.adminpass;
db.collection(channel + "_settings").find({ id: "config" }, function(
err,
docs
) {
if (
docs.length > 0 &&
(docs[0].userpass == undefined ||
docs[0].userpass == "" ||
(msg.hasOwnProperty("pass") && docs[0].userpass == msg.pass))
) {
if (
docs !== null &&
docs.length !== 0 &&
docs[0].adminpass !== "" &&
docs[0].adminpass == hash
) {
db.collection("suggested_thumbnails").update(
{ channel: channel },
{ $set: { thumbnail: msg.thumbnail } },
{ upsert: true },
function(err, docs) {
Notifications.requested_change(
"thumbnail",
msg.thumbnail,
channel
);
socket.emit("toast", "suggested_thumbnail");
}
);
}
} else {
socket.emit("auth_required");
}
});
});
} else {
socket.emit("toast", "thumbnail_denied");
}
}
function description(msg, coll, guid, offline, socket) {
if(msg.description && msg.channel && msg.description.length < 100){
if(typeof(msg.channel) != "string" || typeof(msg.description) != "string") {
var result = {
channel: {
expected: "string",
got: msg.hasOwnProperty("channel") ? typeof(msg.channel) : undefined,
},
pass: {
expected: "string",
got: msg.hasOwnProperty("pass") ? typeof(msg.pass) : undefined,
},
description: {
expected: "string",
got: msg.hasOwnProperty("description") ? typeof(msg.description) : undefined,
},
adminpass: {
expected: "string",
got: msg.hasOwnProperty("adminpass") ? typeof(msg.adminpass) : undefined,
},
};
socket.emit("update_required", result);
return;
}
//coll = coll.replace(/ /g,'');
Functions.getSessionAdminUser(Functions.getSession(socket), coll, function(userpass, adminpass, gotten) {
if(userpass != "" || msg.userpass == undefined) {
msg.userpass = userpass;
}
if(adminpass != "" || msg.adminpass == undefined) {
msg.adminpass = adminpass;
}
var channel = msg.channel.toLowerCase();
var hash = Functions.hash_pass(Functions.hash_pass(Functions.decrypt_string(msg.adminpass), true));
db.collection(channel + "_settings").find({id: "config"}, function(err, docs){
if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (msg.hasOwnProperty('pass') && docs[0].userpass == crypto.createHash('sha256').update(Functions.decrypt_string(msg.pass)).digest("base64")))) {
if(docs !== null && docs.length !== 0 && docs[0].adminpass !== "" && docs[0].adminpass == hash){
db.collection("suggested_descriptions").update({channel: channel}, {$set:{description: msg.description}}, {upsert:true}, function(err, docs){
Notifications.requested_change("description", msg.description, channel);
socket.emit("toast", "suggested_description");
});
}
} else {
socket.emit("auth_required");
}
});
});
} else {
socket.emit("toast", "description_denied");
if (msg.description && msg.channel && msg.description.length < 100) {
if (typeof msg.channel != "string" || typeof msg.description != "string") {
var result = {
channel: {
expected: "string",
got: msg.hasOwnProperty("channel") ? typeof msg.channel : undefined
},
pass: {
expected: "string",
got: msg.hasOwnProperty("pass") ? typeof msg.pass : undefined
},
description: {
expected: "string",
got: msg.hasOwnProperty("description")
? typeof msg.description
: undefined
},
adminpass: {
expected: "string",
got: msg.hasOwnProperty("adminpass")
? typeof msg.adminpass
: undefined
}
};
socket.emit("update_required", result);
return;
}
//coll = coll.replace(/ /g,'');
Functions.getSessionAdminUser(Functions.getSession(socket), coll, function(
userpass,
adminpass,
gotten
) {
if (userpass != "" || msg.pass == undefined) {
msg.pass = userpass;
} else if (msg.hasOwnProperty("pass")) {
msg.pass = crypto
.createHash("sha256")
.update(Functions.decrypt_string(msg.pass))
.digest("base64");
}
if (adminpass != "" || msg.adminpass == undefined) {
msg.adminpass = Functions.hash_pass(adminpass);
} else {
msg.adminpass = Functions.hash_pass(
Functions.hash_pass(Functions.decrypt_string(msg.adminpass), true)
);
}
var channel = msg.channel.toLowerCase();
var hash = msg.adminpass;
db.collection(channel + "_settings").find({ id: "config" }, function(
err,
docs
) {
if (
docs.length > 0 &&
(docs[0].userpass == undefined ||
docs[0].userpass == "" ||
(msg.hasOwnProperty("pass") && docs[0].userpass == msg.pass))
) {
if (
docs !== null &&
docs.length !== 0 &&
docs[0].adminpass !== "" &&
docs[0].adminpass == hash
) {
db.collection("suggested_descriptions").update(
{ channel: channel },
{ $set: { description: msg.description } },
{ upsert: true },
function(err, docs) {
Notifications.requested_change(
"description",
msg.description,
channel
);
socket.emit("toast", "suggested_description");
}
);
}
} else {
socket.emit("auth_required");
}
});
});
} else {
socket.emit("toast", "description_denied");
}
}
function rules(msg, coll, guid, offline, socket) {
if (msg.rules && msg.channel && msg.rules.length < 250) {
if (typeof msg.channel != "string" || typeof msg.rules != "string") {
var result = {
channel: {
expected: "string",
got: msg.hasOwnProperty("channel") ? typeof msg.channel : undefined
},
pass: {
expected: "string",
got: msg.hasOwnProperty("pass") ? typeof msg.pass : undefined
},
rules: {
expected: "string",
got: msg.hasOwnProperty("rules") ? typeof msg.rules : undefined
},
adminpass: {
expected: "string",
got: msg.hasOwnProperty("adminpass")
? typeof msg.adminpass
: undefined
}
};
socket.emit("update_required", result);
return;
}
//coll = coll.replace(/ /g,'');
Functions.getSessionAdminUser(Functions.getSession(socket), coll, function(
userpass,
adminpass,
gotten
) {
if (userpass != "" || msg.pass == undefined) {
msg.pass = userpass;
} else if (msg.hasOwnProperty("pass")) {
msg.pass = crypto
.createHash("sha256")
.update(Functions.decrypt_string(msg.pass))
.digest("base64");
}
if (adminpass != "" || msg.adminpass == undefined) {
msg.adminpass = Functions.hash_pass(adminpass);
} else {
msg.adminpass = Functions.hash_pass(
Functions.hash_pass(Functions.decrypt_string(msg.adminpass), true)
);
}
var channel = msg.channel.toLowerCase();
var hash = msg.adminpass;
db.collection(channel + "_settings").find({ id: "config" }, function(
err,
docs
) {
if (
docs.length > 0 &&
(docs[0].userpass == undefined ||
docs[0].userpass == "" ||
(msg.hasOwnProperty("pass") && docs[0].userpass == msg.pass))
) {
if (
docs !== null &&
docs.length !== 0 &&
docs[0].adminpass !== "" &&
docs[0].adminpass == hash
) {
db.collection("suggested_rules").update(
{ channel: channel },
{ $set: { rules: msg.rules } },
{ upsert: true },
function(err, docs) {
Notifications.requested_change("rules", msg.rules, channel);
socket.emit("toast", "suggested_rules");
}
);
}
} else {
socket.emit("auth_required");
}
});
});
} else {
socket.emit("toast", "rules_denied");
}
}
module.exports.thumbnail = thumbnail;
module.exports.description = description;
module.exports.rules = rules;

View File

@@ -1,24 +1,24 @@
// app/models/user.js
// load the things we need
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var mongoose = require("mongoose");
var bcrypt = require("bcrypt-nodejs");
// define the schema for our user model
var userSchema = mongoose.Schema({
username : String,
password : String,
username: String,
password: String
});
// methods ======================
// generating a hash
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// checking if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.password);
return bcrypt.compareSync(password, this.password);
};
// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);
module.exports = mongoose.model("User", userSchema);

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +1,37 @@
window.addEventListener("DOMContentLoaded", function() {
document.getElementById("login_button").addEventListener("click", function(event) {
event.preventDefault();
document.querySelector("#login_form").submit();
document
.getElementById("login_button")
.addEventListener("click", function(event) {
event.preventDefault();
document.querySelector("#login_form").submit();
});
document.getElementById("login_form").addEventListener("submit", function(event) {
if(this.password.value == "" || this.username.value == ""){
e.preventDefault();
}
document
.getElementById("login_form")
.addEventListener("submit", function(event) {
if (this.password.value == "" || this.username.value == "") {
e.preventDefault();
}
});
if(window.location.pathname == "/signup/" || window.location.pathname == "/signup"){
document.querySelector("#login_form").insertAdjacentHTML("afterbegin", "<input type='text' name='token' placeholder='Token' required autocomplete='off' />");
document.querySelector("#login_form").setAttribute("action", "/signup");
}
if(window.location.hash == "#failed") {
window.location.hash = "";
M.toast({ html: "Couldn't find a user with that username or password..", displayLength: 4000, classes: "red lighten"});
}
if (
window.location.pathname == "/signup/" ||
window.location.pathname == "/signup"
) {
document
.querySelector("#login_form")
.insertAdjacentHTML(
"afterbegin",
"<input type='text' name='token' placeholder='Token' required autocomplete='off' />"
);
document.querySelector("#login_form").setAttribute("action", "/signup");
}
if (window.location.hash == "#failed") {
window.location.hash = "";
M.toast({
html: "Couldn't find a user with that username or password..",
displayLength: 4000,
classes: "red lighten"
});
}
});

View File

@@ -0,0 +1,63 @@
@keyframes snow {
0% {
background-position: 0px 0px, 0px 0px, 0px 0px;
}
100% {
background-position: 500px 500px, 400px 400px, 300px 300px;
}
}
@-moz-keyframes snow {
0% {
background-position: 0px 0px, 0px 0px, 0px 0px;
}
100% {
background-position: 500px 500px, 400px 400px, 300px 300px;
}
}
@-webkit-keyframes snow {
0% {
background-position: 0px 0px, 0px 0px, 0px 0px;
}
100% {
background-position: 500px 500px, 400px 400px, 300px 300px;
}
}
@-ms-keyframes snow {
0% {
background-position: 0px 0px, 0px 0px, 0px 0px;
}
100% {
background-position: 500px 500px, 400px 400px, 300px 300px;
}
}
/*
*
*
* Source: https://codepen.io/NickyCDK/pen/AIonk
*
*/
#snow {
pointer-events: none;
background: none;
font-family: Androgyne;
background-image: url("/assets/images/s1.png"), url("/assets/images/s2.png"),
url("/assets/images/s3.png");
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 1;
-webkit-animation: snow 10s linear infinite;
-moz-animation: snow 10s linear infinite;
-ms-animation: snow 10s linear infinite;
animation: snow 10s linear infinite;
}
#snow.snow-channel {
z-index: 9999;
width: calc(100% - 0.75rem);
height: calc(100% - 32px);
}

View File

@@ -1,4 +1,4 @@
.card-image{
.card-image {
height: 100px;
width: 100px;
background-position: center;
@@ -7,44 +7,63 @@
}
.side_away {
-webkit-transition: all .3s !important;
-moz-transition: all .3s !important;
-o-transition: all .3s !important;
transition: all .3s !important;
-webkit-transition: all 0.3s !important;
-moz-transition: all 0.3s !important;
-o-transition: all 0.3s !important;
transition: all 0.3s !important;
}
.prev.playbar, .skip.playbar {
float: left;
font-size: 24px;
cursor: pointer;
height: 32px;
line-height: 31px;
padding-top: 3px;
.prev.playbar,
.skip.playbar {
float: left;
font-size: 24px;
cursor: pointer;
height: 32px;
line-height: 31px;
padding-top: 3px;
}
.prev, .skip {
.site_loader {
position: absolute;
top: 0;
left: 0;
margin: auto;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 9;
}
.prev,
.skip {
display: flex;
justify-content: center;
align-items: center;
}
#playpause, .prev.playbar, .skip.playbar {
padding: 0 2.5px;
#playpause,
.prev.playbar,
.skip.playbar {
padding: 0 2.5px;
}
.playbar-btn:hover {
background-color: rgba(0,0,0,.6);
color: hsla(0,0%,100%,.5);
background-color: rgba(0, 0, 0, 0.6);
color: hsla(0, 0%, 100%, 0.5);
}
.hide {
display: none!important;
display: none !important;
}
.playbar-btn {
cursor: pointer;
transition: background-color .2s;
cursor: pointer;
transition: background-color 0.2s;
}
#controls, .playbar {
color: #fff;
#controls,
.playbar {
color: #fff;
}
#player_loader_container {
@@ -55,11 +74,12 @@
}
#player_overlay {
position: absolute;
position: relative;
height: calc(100% - 32px);
top: 0px;
left: 0px;
width: 50vw;
width: 60vw;
margin-bottom: 5px;
}
.soundcloud_info_container {
@@ -69,7 +89,7 @@
padding-left: 20px;
display: flex;
align-items: center;
background: rgba(0,0,0,.7);
background: rgba(0, 0, 0, 0.7);
}
.soundcloud_info_container a {
@@ -77,7 +97,7 @@
}
.card {
cursor:pointer;
cursor: pointer;
background-color: rgba(255, 255, 255, 0.04) !important;
}
@@ -100,37 +120,36 @@
}
.video_only {
width:100vw !important;
width: 100vw !important;
height: 100vh !important;
}
#player{
width:50vw;
#player {
width: 60vw;
height: calc(100vh - 32px);
padding-top: 51px;
}
#pageButtons{
#pageButtons {
text-align: center;
padding-top:15px;
padding-top: 15px;
display: flex;
justify-content: space-around;
}
#pageButtons, #pageButtons a{
color:white !important;
}
.prev_page, .next_page{
.prev_page,
.next_page {
cursor: pointer;
}
#wrapper{
height:calc(100% - 56px);
#wrapper {
height: calc(100% - 46px);
}
.prev_page_hide, .next_page_hide{
.prev_page_hide,
.next_page_hide {
visibility: visible !important;
color:gray;
color: gray;
}
.list-song {
@@ -138,26 +157,27 @@
}
#list-song-html {
display:none;
display: none;
}
#song-title{
display:none;
#song-title {
display: none;
}
#zoffchannel{
display:none;
#zoffchannel {
display: none;
}
.list-image, .list-suggested-image{
.list-image,
.list-suggested-image {
width: 34%;
height: 66px;
float: left;
}
.list-image:after {
-webkit-transition: all .3s;
transition: all .3s;
-webkit-transition: all 0.3s;
transition: all 0.3s;
font-family: "Material Icons";
content: "thumb_up";
speak: none;
@@ -174,7 +194,7 @@
height: 100%;
top: 0;
left: 0;
background: rgba(0,0,0,0.8);
background: rgba(0, 0, 0, 0.8);
opacity: 0;
/* transition: all .1s ease; */
display: flex;
@@ -191,162 +211,184 @@
text-transform: none;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
content: "\e625";/*"\e800";*/
color:white;
font-size:65px;
position:absolute;
width:100%; height:100%;
top:0; left:0;
background:rgba(0,0,0,0.8);
opacity:0;
transition: all .1s ease;
content: "\e625"; /*"\e800";*/
color: white;
font-size: 65px;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.8);
opacity: 0;
transition: all 0.1s ease;
}
.vote-container:hover .list-image:after, .add-suggested:hover .list-suggested-image:after {
opacity:1;
.vote-container:hover .list-image:after,
.add-suggested:hover .list-suggested-image:after {
opacity: 1;
}
.vote-span{
.vote-span {
opacity: 0.7;
padding: 0 0 0 10px;
color:white !important;
color: white !important;
}
.list-song{
.list-song {
background-color: rgba(255, 255, 255, 0.04);
color:white;
font:12px Arial,sans-serif;
-webkit-transition:height .3s;
-moz-transition:height .3s;
-o-transition:height .3s;
transition:height .3s;
height:66px;
color: white;
font: 12px Arial, sans-serif;
-webkit-transition: height 0.3s;
-moz-transition: height 0.3s;
-o-transition: height 0.3s;
transition: height 0.3s;
height: 66px;
width: 100%;
}
.list-song .card-content{padding:0;}
.list-title{
font-size:13px !important;
display:block;
color:white;font-size:1em;
text-align:left;
.list-song .card-content {
padding: 0;
}
.list-title {
font-size: 13px !important;
display: block;
color: white;
font-size: 1em;
text-align: left;
padding: 0 10px 0 10px;
line-height: 2.6rem;
}
.card-image{cursor:pointer}
.card{
.card-image {
cursor: pointer;
}
.card {
margin: 2.5px 0 2.5px 0 !important;
}
.card:hover{
box-shadow: 0 5px 5px 0 rgba(0,0,0,0.16), 0 5px 10px 0 rgba(0,0,0,0.12);
.card:hover {
box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.16), 0 5px 10px 0 rgba(0, 0, 0, 0.12);
}
#playlist{
/*background-color:grey;*/
height:100vh;
width:50vw;
overflow:hidden;
#playlist {
height: 100vh;
width: 40vw;
overflow: hidden;
padding-left: 10px;
padding-right: 10px;
padding-top: 5px;
}
#zoffbutton{
cursor:pointer;
position: absolute;
bottom: 35px;
left: 10px;
background-image: url('/assets/images/z.svg');
width: 50px;
#zoffbutton {
cursor: pointer;
background-image: url(/assets/images/z.svg);
width: 90px;
height: 50px;
background-position: center;
background-size: 135%;
background-position: 50%;
background-size: 85%;
background-repeat: no-repeat;
}
.progress{background-color:rgba(0,0,0,0) !important;}
.indeterminate {
background-color:white !important;
.progress {
background-color: rgba(0, 0, 0, 0) !important;
}
#controls
{
.indeterminate {
background-color: white !important;
}
#controls {
background: inherit;
position: relative;
opacity:0;
height:32px;
width:50vw;
color:white;
margin-top:-5px;
opacity: 0;
height: 32px;
width: 60vw;
color: white;
margin-top: -5px;
}
#playpause, #duration, #volume-button
{
float:left;
color:white;
#playpause,
#duration,
#volume-button {
float: left;
color: white;
}
.margin-playbar {
margin-left: 10px;
}
#seekToDuration{
position: absolute;
background: #2d2d2d;
color:white;
padding: 10px 8px;
z-index: 2000;
background-color: #2d2d2d;
border-radius: 2px;
color: #fff;
min-height: 36px;
text-align: center;
max-width: calc(100% - 4px);
pointer-events: none;
#seekToDuration {
position: absolute;
background: #2d2d2d;
color: white;
padding: 10px 8px;
z-index: 2000;
background-color: #2d2d2d;
border-radius: 2px;
color: #fff;
min-height: 36px;
text-align: center;
max-width: calc(100% - 4px);
pointer-events: none;
}
#playpause, #volume-button
{
#playpause,
#volume-button {
font-size: 23px;
}
#playpause:hover, #volume-button:hover, #fullscreen:hover
{
color:rgba(255,255,255,0.5);
#playpause:hover,
#volume-button:hover,
#fullscreen:hover {
color: rgba(255, 255, 255, 0.5);
}
#fullscreen
{
float:right;
color:white;
margin-right:15px;
#fullscreen {
float: right;
color: white;
margin-right: 15px;
}
#duration, #viewers
{
margin-top:5px;
font-family:"Roboto", sans-serif;
font-weight:300;
margin-left:15px;
margin-right:5px;
#duration,
#viewers {
margin-top: 5px;
font-family: "Roboto", sans-serif;
font-weight: 300;
margin-left: 15px;
margin-right: 10px;
}
#viewers{
.channel-info-container {
align-items: center;
display: flex;
position: absolute;
bottom: 50px;
left: 0px;
background: rgba(0, 0, 0, 0.5);
padding-left: 5px;
padding-right: 25px;
}
.channel-title {
margin-left: -20px;
}
#viewers {
float: right;
display: flex;
align-items: center;
}
#play, #pause, #volume-button, #fullscreen
{
font-size:20px;
cursor:pointer;
#play,
#pause,
#volume-button,
#fullscreen {
font-size: 20px;
cursor: pointer;
}
.ui-slider-vertical {
width: .8em;
width: 0.8em;
height: 100px;
}
.ui-slider {
@@ -365,16 +407,16 @@
.ui-slider .ui-slider-range {
position: absolute;
z-index: 1;
font-size: .7em;
font-size: 0.7em;
display: block;
border: 0;
background-position: 0 0;
}
.ui-slider-vertical .ui-slider-handle {
left: -.3em;
left: -0.3em;
margin-left: 0;
margin-bottom: -.6em;
margin-bottom: -0.6em;
}
.ui-slider .ui-slider-handle {
position: absolute;
@@ -397,27 +439,27 @@
.ui-slider .ui-slider-range {
position: absolute;
z-index: 1;
font-size: .7em;
font-size: 0.7em;
display: block;
border: 0;
background-position: 0 0;
}
.ui-slider-horizontal .ui-slider-handle {
top: -.3em;
margin-left: -.6em;
top: -0.3em;
margin-left: -0.6em;
}
#volume {
border-radius: 10px;
cursor:pointer;
float:left;
cursor: pointer;
float: left;
position: relative;
left: 10px;
margin: 13px auto;
height:5px;
height: 5px;
width: 75px;
/*background-color:rgba(0, 0, 0, 0.5);*/
background:rgba(0, 0, 0, 0.5) 50% 50% repeat-x;
background: rgba(0, 0, 0, 0.5) 50% 50% repeat-x;
border: none;
outline: none;
/*border-radius: 2px;*/
@@ -460,7 +502,8 @@
display: none;
}
#volume .volume-handle.ui-state-active {
box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.01), 0 0 0 7px rgba(255,255,255,0.3);
box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.01),
0 0 0 7px rgba(255, 255, 255, 0.3);
position: absolute;
width: 14px;
height: 14px;
@@ -468,10 +511,10 @@
background: #dadada;
}
#toast-container{
left:2%;
cursor:pointer;
width:70vw;
#toast-container {
left: 2%;
cursor: pointer;
width: 70vw;
display: flex;
flex-direction: column;
align-items: baseline;
@@ -483,29 +526,25 @@
cursor: pointer;
}
.play
{
.play {
background-size: auto;
width: 55px;
height: 27px;
}
.pause
{
.pause {
background-size: auto;
width: 55px;
height: 27px;
}
.hide
{
display:none !important;
.hide {
display: none !important;
}
#bar
{
height:100%;
background-color:rgba(0,0,0,0.5);
#bar {
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
html {
@@ -516,45 +555,75 @@ html {
background: inherit;
}
#pageButtons, #pageButtons a{
color:white !important;
#pageButtons,
#pageButtons a {
color: white !important;
width: 100%;
justify-content: space-evenly;
align-items: center;
}
#pageNumber{
#pageButtons a,
#pageButtons span {
padding-left: 1px;
padding-right: 1px;
}
#pageNumber {
cursor: default;
color: white;
padding:0;
padding: 0;
display: inline-flex;
align-items: center;
height: 36px;
justify-content: center;
width: 100%;
}
.prev_page, .next_page, .last_page, .first_page{
.prev_page,
.next_page,
.last_page,
.first_page {
cursor: pointer;
}
.prev_page_hide, .next_page_hide, .last_page_hide, .first_page_hide{
.prev_page_hide,
.next_page_hide,
.last_page_hide,
.first_page_hide {
visibility: visible !important;
color:gray;
cursor:default;
color: gray;
cursor: default;
height: 32px;
line-height: 36px;
width: 100%;
justify-content: center;
}
.prev_page_hide, .prev_page, .first_page, .first_page_hide{
padding:0 1px;
.prev_page_hide,
.prev_page,
.first_page,
.first_page_hide {
padding: 0 1px;
height: 32px;
line-height: 36px;
}
.next_page_hide, .next_page, .last_page, .last_page_hide{
padding:0 0px;
.next_page_hide,
.next_page,
.last_page,
.last_page_hide {
padding: 0 0px;
display: flex;
}
.first_page, .first_page_hide {
.first_page,
.first_page_hide {
padding: 0 0 0 10px;
}
.last_page, .last_page_hide {
.last_page,
.last_page_hide {
padding: 0 10px 0 0;
}
@@ -572,17 +641,27 @@ body {
position: absolute;
bottom: 0px;
left: 0px;
background: rgba(0,0,0,.7);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 0 5px;
}
#song-title {
position: absolute;
z-index: 9;
color: white;
background: rgba(0, 0, 0, 0.5);
font-size: 1.5rem;
padding: 10px;
width: 60vw;
}
/*
.last_page, .last_page_hide, .first_page, .first_page_hide{
display: none !important;
}
*/
#wrapper{
#wrapper {
background: inherit;
/*height: 94%;*/
}
@@ -592,3 +671,46 @@ display: none !important;
bottom: 90px;
}
}
@media only screen and (max-width: 736px) and (max-width: 500px),
only screen and (max-device-width: 736px) and (orientation: landscape) {
#player-container {
/*display: none;*/
position: absolute;
width: 100vw;
height: 200px;
bottom: 0px;
}
#controls {
width: 100vw;
margin-top: 0px;
}
#player {
width: 100vw;
height: 170px;
display: block;
}
#player_overlay {
position: relative;
width: 100vw;
margin-bottom: 0px;
}
#playlist {
width: 100vw;
height: calc(100vh - 208px);
}
#toast-container {
min-width: 96%;
bottom: auto;
}
#song-title {
width: 100vw;
font-size: 1.2rem;
top: calc(100vh - 200px);
}
}

View File

@@ -0,0 +1,54 @@
.material-icons {
display: none;
width: 24px;
}
html {
background: #2d2d2d;
}
body {
background: white;
}
a {
outline: 0 !important;
}
body {
display: flex;
min-height: 100vh;
flex-direction: column;
overflow-x: hidden;
-webkit-transition: background-color 1s;
-moz-transition: background-color 1s;
-ms-transition: background-color 1s;
-o-transition: background-color 1s;
transition: background-color 1s;
overflow-y: scroll !important;
}
input[type="text"]:focus:not([readonly]),
input[type="password"]:focus:not([readonly]),
input[type="email"]:focus:not([readonly]),
input[type="url"]:focus:not([readonly]),
input[type="time"]:focus:not([readonly]),
input[type="date"]:focus:not([readonly]),
input[type="datetime-local"]:focus:not([readonly]),
input[type="tel"]:focus:not([readonly]),
input[type="number"]:focus:not([readonly]),
input[type="search"]:focus:not([readonly]),
textarea.materialize-textarea:focus:not([readonly]) {
border-bottom: 1px solid #9d9d9d;
box-shadow: 0 1px 0 0 #9d9d9d;
}
nav ul li:hover,
nav ul li.active {
background-color: rgba(0, 0, 0, 0.1);
}
* {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-moz-tap-highlight-color: rgba(0, 0, 0, 0);
}

View File

@@ -0,0 +1,858 @@
@media only screen and (min-width: 993px) {
.toast {
float: left;
}
nav .zbrand {
left: 0px !important;
}
}
@media screen and (-webkit-min-device-pixel-ratio: 0) {
#wrapper {
padding-right: 0vh !important;
width: 100% !important;
overflow: hidden;
}
}
@media only screen and (max-width: 992px) {
nav .brand-logo {
left: 0%;
transform: translateX(0%);
-webkit-transform: translateX(0%);
padding-left: 0px;
}
.zbrand {
/*max-width: 35%;*/
}
}
@media (min-width: 600px),
(min-width: 961px),
(min-width: 1025px),
(min-width: 1281px) {
#controls {
background: none !important;
}
}
@media only screen and (max-width: 736px) and (max-width: 600px),
only screen and (max-device-width: 736px) and (orientation: landscape) {
.autocomplete-content.dropdown-content {
width: 95vw !important;
}
.mobile-overflow {
overflow: visible;
}
.footer-buttons,
.footer-buttons li a {
width: 100%;
}
#main-row {
margin-right: -3px !important;
background: inherit;
}
.admin_panel {
margin-top: 25px !important;
}
#suggestions {
height: auto !important;
/*padding-bottom: 0px;*/
}
.margin-playbar {
margin-left: 10px;
}
#chat-container {
height: calc(100vh - 48px - 64px - 120px);
margin-bottom: 18px;
}
#player_bottom_overlay {
top: 7px;
}
.mobile-delete {
height: 100%;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
width: 60px;
top: 0px;
right: -60px;
/* overflow: visible; */
z-index: -99999999;
}
#main-container {
/*padding-bottom: 20px;*/
}
#fireplace_player {
display: none !important;
}
.addedJoinBox {
display: none;
}
#playbar {
display: block;
position: fixed;
bottom: 0px;
z-index: 1000;
left: 0;
right: 0;
}
.list-title {
width: 66%;
}
.hamburger-sidenav {
margin: 20px 10px 12px 10px;
}
#main_section_frontpage {
margin-top: -20px;
padding-top: 0px;
}
.delete_button,
.del_suggested,
.del_user_suggested {
bottom: -9px;
/* line-height: inherit; */
height: auto;
display: flex;
align-items: center;
border-top: none;
padding: 0px !important;
margin: 0px !important;
}
.vote-container:hover .list-image:after,
.add-suggested:hover .list-suggested-image:after {
opacity: 1;
content: "thumb_up";
}
.list-image:after,
.list-suggested-image:after {
content: none;
}
.delete_button .material-icons,
.del_suggested .material-icons,
.del_user_suggested .material-icons {
font-size: 2.5rem;
}
#remote-sidebar-buttons-container {
text-align: center;
}
.slider-vol-mobile {
display: none !important;
}
#frontpage-viewer-counter {
right: 56px;
width: 62px;
left: inherit;
text-align: right;
}
.brand-logo {
left: 0 !important;
padding-left: 0px !important;
-webkit-transform: translateX(0%) !important;
-moz-transform: translateX(0%) !important;
-ms-transform: translateX(0%) !important;
-o-transform: translateX(0%) !important;
transform: translateX(0%) !important;
}
#player_overlay {
height: calc(30vh);
bottom: -33px !important;
top: 7px;
width: 100vw;
height: 200px;
pointer-events: all;
display: none;
}
#wrapper {
min-height: 75px;
}
.click-through {
pointer-events: none;
}
.zicon {
height: 100%;
}
/*.list-remove{
margin-top:-68px;
}*/
#settings-bar {
overflow-x: hidden;
}
#remote-mobile-container {
margin-left: -7px;
}
#remote_channel {
color: #2d2d2d;
/*width:90%;*/
}
.show-only-mobile {
display: block;
}
#volume-control-remote {
display: none;
}
#remote_header {
color: #2d2d2d;
font-size: 1.5em;
padding: 10px;
text-align: center;
}
#all_chat,
#channelchat {
height: calc(100vh - 352px);
}
#fp-nav {
width: 100%;
}
#search-wrapper {
width: 100vw;
}
#search-wrapper:hover,
#song-title:hover {
/*background: inherit;*/
}
#toast-container {
left: 0% !important;
width: 100vw;
bottom: 55px;
}
.empty-inner-results {
height: 100vh !important;
}
#empty-results {
height: calc(100vh - 112px);
}
.search_input {
padding-right: 50px;
width: calc(100vw - 78px);
}
.playlist-tabs-loggedIn,
.playlist-tabs {
width: calc(100%) !important;
}
#wrapper.tabs_height {
height: calc(100vh - 48px - 64px - 134px);
overflow: initial;
}
.client-wrapper {
height: calc(100vh - 48px - 64px - 36px) !important;
}
/*.client-results-height {
margin-top: 50px !important;
}*/
.client-pagination-height {
height: 80px;
}
.brand-mobile {
padding-left: 0px !important;
}
#player {
height: calc(100%);
display: none;
width: 100vw;
}
.pointer-events-all-mobile {
pointer-events: all !important;
}
.small-display {
display: block !important;
}
.small-display-hide {
display: none !important;
}
.hide-on-small-only {
display: none;
}
#controls {
/*opacity: 1;*/
overflow: initial;
background-color: rgb(70, 70, 70);
height: 50px;
margin-top: inherit;
bottom: 0px;
position: fixed;
pointer-events: all;
-webkit-transition: background-color 0.5s ease;
-moz-transition: background-color 0.5s ease;
-o-transition: background-color 0.5s ease;
transition: background-color 0.5s ease;
}
#chat-container {
padding-left: 10px;
}
#play,
#pause,
#volume-button i,
#fullscreen i,
.castButton-unactive i,
.castButton-active i,
.playbar-btn i {
font-size: 31px;
font-size: 31px !important;
margin-top: 8px;
line-height: 31px;
}
.skip.playbar,
.prev.playbar,
#playpause {
padding-top: 0px;
height: 51px;
}
.castButton-unactive,
.castButton-active {
margin-right: 10px;
padding-right: 10px;
padding-left: 0px;
}
/*#volume{
display: none;
}*/
.volume-container {
position: absolute;
right: 0%;
width: 37px;
top: -127px;
height: 127px;
left: auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: inherit;
}
.volume-container-cast {
right: 39px;
}
#volume {
width: 10px;
height: 100px;
left: 0px;
}
.ui-widget-header {
background: rgb(255, 255, 255);
}
#viewers {
margin-top: 8px;
font-size: 20px;
font-weight: 400;
}
.footer-copyright {
margin-bottom: 10px;
}
#duration {
font-size: 20px;
font-weight: 400;
margin-top: 9px;
letter-spacing: -0.7px;
margin-left: 10px;
}
#volume-button {
float: right;
/* margin-right: 5px; */
padding-right: 3px;
margin-left: 0px;
padding-left: 3px;
height: 51px;
padding-top: 0px;
width: 37px;
}
#fullscreen {
float: right;
}
.castButton {
width: 39px;
height: 51px;
padding-top: 0em;
}
.label-for-mobile-frontpage {
display: initial;
width: auto !important;
margin-left: auto !important;
}
.mega {
background: white;
}
#bar {
background-color: rgba(0, 0, 0, 1);
}
.channel-finder .input-field {
padding: 0 0.75rem;
}
.mega form {
display: block;
width: auto;
margin-bottom: 0px;
}
.mega input {
color: black;
text-shadow: none;
margin-left: 0px !important;
padding-left: 0px !important;
}
.room-namer.autocomplete {
margin-left: 0px !important;
margin-top: auto !important;
}
#channel-share-modal {
width: 100%;
}
#autocomplete-input {
width: 100%;
border-bottom: 1px solid #9e9e9e !important;
}
#autocomplete-input::-webkit-input-placeholder {
/* WebKit browsers */
color: #fff;
}
#autocomplete-input:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: #fff;
opacity: 1;
}
#autocomplete-input::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: #fff;
opacity: 1;
}
#autocomplete-input:-ms-input-placeholder {
/* Internet Explorer 10+ */
color: #fff;
}
.room-namer::-webkit-input-placeholder {
/*color:rgb(155, 155, 155) !important;*/
-webkit-transition: opacity 0.5s;
color: transparent !important;
}
#mega-background,
.mega h5,
#snow,
.pitch,
.channel-finder .input-field .prefix,
.listen-button {
display: none !important;
}
.channel-finder .input-field {
display: initial;
/* width: 69%; */
justify-content: center;
}
/*.mega {display:none;}*/
.mobile-search {
display: block;
}
.toast {
height: auto;
}
.remote-panel {
display: none;
}
.navbar-fixed,
#nav {
/*position: relative;*/
}
.navbar-fixed {
height: 100px;
margin-bottom: 25px;
}
.control-list {
position: absolute !important;
/*width: 120px;*/
}
.client-control-list {
width: auto;
}
.page-footer {
padding-top: 40px !important;
}
.padding-bottom-novideo {
padding-bottom: 40px;
}
.padding-bottom-extra {
padding-bottom: 210px;
}
.main,
#main-row,
.video-container,
#playlist {
height: auto !important;
margin-bottom: 2px;
margin-top: -6px;
}
.main {
max-width: 99%;
background: inherit;
}
#pageButtons {
margin-left: -11px;
width: 100vw;
position: relative;
padding-bottom: 3px;
}
#search_loader {
height: 56px;
}
#playlist {
/*margin-left: 10px;*/
background: inherit;
width: calc(100% - 10px);
overflow: hidden;
}
#player {
pointer-events: none;
margin-top: 7px;
}
.search-container,
.song-title {
background: inherit;
}
.row .col.s12 {
width: 100% !important;
}
#main-row.row #video-container.video-container {
position: fixed;
display: block !important;
width: 106vw !important;
height: 200px !important;
z-index: 10;
bottom: 55px;
}
#video-container.video-container.frontpage-player {
width: auto !important;
}
.chan {
text-shadow: 0px 0px 0px rgba(0, 0, 0, 0.42);
width: calc(100vw - 170px) !important;
max-width: calc(100% - 87.5px - 130px);
font-size: 2rem;
padding-right: 0px;
overflow: hidden;
/* display: block; */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.chan-client {
max-width: calc(100% - 87.5px - 170px);
}
.control-list li a {
min-width: 0px;
width: 37px;
padding: 0 0 0 0px;
}
nav .zbrand {
-webkit-transform: initial;
transform: initial;
display: flex;
max-width: initial;
width: 100vw;
-webkit-box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),
0 3px 1px -2px rgba(0, 0, 0, 0.2);
}
.title-container {
background-color: rgba(0, 0, 0, 0.1);
display: block;
top: 56px !important;
width: 100vw;
background: #2d2d2d;
}
.title-container li {
/*width: 100%;*/
}
#inner-results {
height: calc(100vh - 54px - 64px - 123px);
overflow-y: scroll;
overflow-x: hidden;
}
.thumb-and-info {
flex-direction: column;
}
.result_info {
opacity: 0.8;
margin-top: 0px;
height: 21px;
margin-right: 0px;
padding: 0px;
line-height: initial;
border-top-right-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
width: 55px;
margin-left: 10px;
margin-top: -16px;
}
.search_results {
margin-top: 45px;
background: #000;
}
.results-tabs .indicator {
margin-top: 50px;
}
#results,
#results_soundcloud {
background-color: #000;
margin-top: -8px;
}
#results {
max-height: calc(100vh - 165px);
}
#results_soundcloud {
height: calc(100vh - 64px - 54px);
}
#results_soundcloud #inner-results {
height: calc(100vh - 54px - 64px - 47px);
}
.result {
margin: 0;
width: 99%;
}
.result-get-more-info {
background: black;
position: absolute;
right: 0px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
width: 45px;
}
.result-info-no-buttons {
width: calc(100% - 200px);
}
.result-object {
-webkit-transform: translateX(0%);
transform: translateX(0%);
overflow: hidden;
}
.result {
-webkit-transition: margin 0.5s;
-moz-transition: margin 0.5s;
transition: margin 0.5s;
}
#user_password {
width: 80% !important;
}
#addToListInput {
top: -85px;
right: 35px;
}
#addToOtherList {
padding: 0 10px;
}
.result-object-slid {
/*-webkit-transform: translateX(calc(-100% + 45px)) !important;
transform: translateX(calc(-100% + 45px)) !important;*/
margin-left: -94%;
}
.result-start-end-container {
/*visibility: hidden;
pointer-events: none;*/
margin-left: 120%;
position: relative;
top: -10px;
}
.result-info-buttons {
margin-top: 20px;
width: 150px;
}
.result .search-title {
white-space: nowrap;
width: calc(100vw - 165px);
margin-top: -5px;
z-index: 9999;
}
.result img {
margin: -3px 10px;
height: 50px;
width: 88.88px;
}
.result .add-many {
margin-top: 15px;
}
}
@media only screen and (max-device-width: 736px) and (orientation: landscape) {
.video-container {
width: 315px !important;
/* height: auto !important; */
right: -5px;
bottom: 20px;
}
}
@media only screen and (max-width: 768px) {
#results {
background-color: #000;
/*margin-top:56px;*/
}
.title-container {
top: 64px;
top: 0px;
}
}
@media only screen and (min-width: 769px) {
.navbar-fixed {
height: 64px;
}
nav .zbrand {
/*display: inline-block;*/
/*top:-22px;*/
/*left:100px;*/
}
.title-container li {
/*width: 71%;*/
}
#wrapper {
height: 100%;
width: 100%;
overflow: auto;
opacity: 1;
overflow: hidden;
padding-right: 0.5rem !important;
}
#playlist {
/*padding:0px 15px;*/
height: 90%;
height: calc(100vh - 64px);
overflow: hidden;
padding-right: 0px;
/*padding-right: 0px;*/
/*padding:0px 0px 0px 0px;*/
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,176 +1,175 @@
<!DOCTYPE html>
<html>
<head>
<title>Zoff OAuth Callback</title>
<script type="text/javascript" src="/assets/dist/callback.min.js"></script>
<meta charset="UTF-8"/>
<style>
@-webkit-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-webkit-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-moz-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-ms-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-moz-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-webkit-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-o-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.uil-ring-css {
background: none;
width: 190px;
height: 190px;
transform: scale(1);
position: absolute;
left: 0;
right: 0;
margin: auto;
top: 0;
bottom: 0;
}
.uil-ring-css > div {
position: absolute;
width: 150px;
height: 150px;
border: 20px solid black;
border-radius: 50%;
border-bottom-color: transparent;
border-left-color: transparent;
transform: rotate(-45deg);'
-ms-animation: uil-ring-anim 1s linear infinite;
-moz-animation: uil-ring-anim 1s linear infinite;
-webkit-animation: uil-ring-anim 1s linear infinite;
-o-animation: uil-ring-anim 1s linear infinite;
animation: uil-ring-anim 1s linear infinite;
}
h4 {
text-align: center;
font-family: sans-serif;
font-size: 2rem;
}
</style>
</head>
<body>
<h4>Loading..</h4>
<div class="uil-ring-css" >
<div></div>
</div>
</body>
<head>
<title>Zoff OAuth Callback</title>
<script src="https://connect.soundcloud.com/sdk/sdk-3.3.0.js"></script>
<script type="text/javascript" src="/assets/dist/callback.min.js"></script>
<meta charset="UTF-8" />
<style>
@-webkit-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-webkit-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-moz-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-ms-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-moz-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-webkit-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-o-keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes uil-ring-anim {
0% {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.uil-ring-css {
background: none;
width: 190px;
height: 190px;
transform: scale(1);
position: absolute;
left: 0;
right: 0;
margin: auto;
top: 0;
bottom: 0;
}
.uil-ring-css > div {
position: absolute;
width: 150px;
height: 150px;
border: 20px solid black;
border-radius: 50%;
border-bottom-color: transparent;
border-left-color: transparent;
transform: rotate(-45deg);'
-ms-animation: uil-ring-anim 1s linear infinite;
-moz-animation: uil-ring-anim 1s linear infinite;
-webkit-animation: uil-ring-anim 1s linear infinite;
-o-animation: uil-ring-anim 1s linear infinite;
animation: uil-ring-anim 1s linear infinite;
}
h4 {
text-align: center;
font-family: sans-serif;
font-size: 2rem;
}
</style>
</head>
<body>
<h4>Loading..</h4>
<div class="uil-ring-css"><div></div></div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -1,243 +1,351 @@
var Admin = {
beginning: true,
logged_in: false,
beginning:true,
logged_in: false,
update_strict_skip: function(value) {
var form = document.getElementById("adminSettingsForm");
form.strictSkipNumber = value;
Admin.submitAdmin(form, false);
},
pw: function(msg) {
Admin.logged_in = msg;
if (!msg) return;
w_p = false;
M.Modal.init(document.getElementById("channel_info"));
if (Admin.logged_in) {
Helper.removeClass(".info_change_li", "hide");
Helper.removeClass("#user_suggests", "hide");
Helper.removeClass("#user-suggest-html", "hide");
if (
Helper.html(".suggested-badge") != "0" &&
Helper.html(".suggested-badge") != ""
) {
Helper.removeClass(".suggested-badge", "hide");
}
if (conf != undefined && conf.strictSkip) {
Helper.removeClass(".strict-skip-input", "hide");
}
} else {
Admin.hideUserSuggested();
Helper.addClass(".strict-skip-input", "hide");
}
Helper.removeClass(".delete-context-menu", "context-menu-disabled");
names = [
"vote",
"addsongs",
"longsongs",
"frontpage",
"allvideos",
"removeplay",
"skip",
"shuffle",
"userpass",
"toggleChat",
"strictSkip"
];
//Crypt.set_pass(chan.toLowerCase(), Crypt.tmp_pass);
pw: function(msg) {
Admin.logged_in = msg;
if(!msg) return;
w_p = false;
if(Admin.logged_in) {
Helper.css("#thumbnail_form", "display", "inline-block");
Helper.css("#description_form", "display", "inline-block");
Helper.removeClass("#user_suggests", "hide");
Helper.removeClass("#user-suggest-html", "hide");
if(Helper.html(".suggested-badge") != "0" && Helper.html(".suggested-badge") != "") {
Helper.removeClass(".suggested-badge", "hide");
}
} else {
Admin.hideUserSuggested();
}
Helper.removeClass(".delete-context-menu", "context-menu-disabled");
names = ["vote","addsongs","longsongs","frontpage", "allvideos",
"removeplay", "skip", "shuffle", "userpass"];
//Crypt.set_pass(chan.toLowerCase(), Crypt.tmp_pass);
for (var i = 0; i < names.length; i++) {
document.getElementsByName(names[i])[0].removeAttribute("disabled");
}
Helper.removeClass(".card-action", "hide");
Helper.addClass("#admin-lock", "clickable");
document.getElementById("admin-lock").innerHTML = "lock_open";
if(!Helper.mobilecheck()){
Helper.tooltip('#admin-lock', {
delay: 5,
position: "left",
html: "Logout"
});
}
document.getElementById("password").value = "";
document.getElementById("password").setAttribute("placeholder", "Change admin password");
Helper.removeClass(".user-password-li", "hide");
Helper.removeClass(".delete-all", "hide");
if(document.getElementsByClassName("password_protected")[0].checked) {
Helper.removeClass(".change_user_pass", "hide");
}
if(Helper.html("#admin-lock") != "lock_open"){
Helper.addClass("#admin-lock", "clickable");
document.getElementById("admin-lock").innerHTML = "lock_open";
if(!Helper.mobilecheck()){
Helper.tooltip('#admin-lock', {
delay: 5,
position: "left",
html: "Logout"
});
}
}
},
hideUserSuggested: function() {
Helper.addClass("#user_suggests", "hide")
Helper.addClass("#user-suggest-html", "hide");
Helper.addClass(".suggested-badge", "hide");
},
conf: function(msg) {
if(msg[0].adminpass == ""){
////Crypt.remove_pass(chan.toLowerCase());
}
Admin.set_conf(msg[0]);
if(msg[0].adminpass !== "" && Admin.beginning){
//emit("password", {password: Crypt.crypt_pass(Crypt.get_pass(chan.toLowerCase())), channel: chan.toLowerCase()});
Admin.beginning = false;
}
},
pass_save: function() {
if(!w_p) {
//emit('password', {password: Crypt.crypt_pass(CryptoJS.SHA256(document.getElementById("password").value).toString()), channel: chan.toLowerCase(), oldpass: Crypt.crypt_pass(Crypt.get_pass(chan.toLowerCase()))});
emit('password', {password: Crypt.crypt_pass(document.getElementById("password").value), channel: chan.toLowerCase()});
} else {
//emit('password', {password: Crypt.crypt_pass(CryptoJS.SHA256(document.getElementById("password").value).toString()), channel: chan.toLowerCase()});
emit('password', {password: Crypt.crypt_pass(document.getElementById("password").value), channel: chan.toLowerCase()});
}
},
log_out: function() {
before_toast();
/*if(Crypt.get_pass(chan.toLowerCase())) {*/
//Crypt.remove_pass(chan.toLowerCase());
if(Admin.logged_in) {
socket.emit("logout");
M.toast({html: "Logged out", displayLength: 4000});
Admin.display_logged_out();
} else {
M.toast({html: "Not logged in", displayLength: 4000});
}
},
display_logged_out: function() {
Admin.logged_in = false;
w_p = true;
adminpass = "";
names = ["vote","addsongs","longsongs","frontpage", "allvideos",
"removeplay", "skip", "shuffle"];
document.getElementById("password").value = "";
Helper.css("#thumbnail_form", "display", "none");
Helper.css("#description_form", "display", "none");
for (i = 0; i < names.length; i++) {
document.getElementsByName(names[i])[0].setAttribute("disabled", true);
}
if(Helper.html("#admin-lock") != "lock") {
if(!Helper.mobilecheck()) {
Helper.tooltip('#admin-lock', "destroy");
}
Helper.removeClass("#admin-lock", "clickable");
document.getElementById("admin-lock").innerHTML = "lock";
}
Helper.addClass(".user-password-li", "hide");
Helper.addClass(".delete-all", "hide");
if(document.getElementsByClassName("password_protected")[0].checked) {
Helper.removeClass(".change_user_pass", "hide");
}
Helper.addClass(".change_user_pass", "hide");
Admin.hideUserSuggested();
Helper.removeClass("#admin-lock", "clickable");
document.getElementById("password").setAttribute("placeholder", "Enter admin password");
Helper.addClass(".delete-context-menu", "context-menu-disabled");
},
save: function(userpass) {
Admin.submitAdmin(document.getElementById("adminForm").elements, userpass);
},
set_conf: function(conf_array) {
conf = conf_array;
music = conf_array.allvideos;
longsongs = conf_array.longsongs;
names = ["vote","addsongs","longsongs","frontpage", "allvideos",
"removeplay", "skip", "shuffle", "userpass"];
hasadmin = conf_array.adminpass != "";
var show_disabled = true;
if(hasadmin && Admin.logged_in || !hasadmin) {
show_disabled = false;
}
for (var i = 0; i < names.length; i++) {
document.getElementsByName(names[i])[0].checked = (conf_array[names[i]] === true);
if(show_disabled) {
document.getElementsByName(names[i])[0].setAttribute("disabled", show_disabled);
} else {
document.getElementsByName(names[i])[0].removeAttribute("disabled");
}
}
if((hasadmin) && !Admin.logged_in) {
if(Helper.html("#admin-lock") != "lock") Admin.display_logged_out();
} else if(!hasadmin) {
document.getElementById("password").setAttribute("placeholder", "Create admin password");
} else {
if(document.getElementsByClassName("password_protected")[0].checked) {
Helper.removeClass(".change_user_pass", "hide");
}
}
if(!document.getElementsByClassName("password_protected")[0].checked) {
Helper.addClass(".change_user_pass", "hide");
//Crypt.remove_userpass(chan.toLowerCase());
}
if(conf_array.thumbnail != undefined && conf_array.thumbnail != "") {
document.getElementById("thumbnail_image").innerHTML = "<img id='thumbnail_image_channel' src='" + conf_array.thumbnail + "' alt='thumbnail' />";
}
if(conf_array.description != undefined && conf_array.description != "") {
document.getElementById("description_area").innerHTML = conf_array.description;
}
},
submitAdmin: function(form, userpass_changed) {
voting = form.vote.checked;
addsongs = form.addsongs.checked;
longsongs = form.longsongs.checked;
frontpage = form.frontpage.checked;
allvideos = form.allvideos.checked;
removeplay = form.removeplay.checked;
skipping = form.skip.checked;
shuffling = form.shuffle.checked;
var pass_send = userpass_changed && !form.userpass.checked ? "" : userpass;
configs = {
channel: chan.toLowerCase(),
voting: voting,
addsongs: addsongs,
longsongs: longsongs,
frontpage: frontpage,
allvideos: allvideos,
removeplay: removeplay,
adminpass: adminpass == "" ? "" : Crypt.crypt_pass(adminpass),
skipping: skipping,
shuffling: shuffling,
userpass: Crypt.crypt_pass(pass_send),
userpass_changed: userpass_changed
};
emit("conf", configs);
},
hide_settings: function() {
var sidenavElem = document.getElementsByClassName("sidenav")[0];
M.Sidenav.getInstance(sidenavElem).close();
},
shuffle: function() {
if(!offline) {
//var u = Crypt.crypt_pass(Crypt.get_userpass(chan.toLowerCase()), true);
//if(u == undefined) u = "";
emit('shuffle', {channel: chan.toLowerCase()});
} else {
for(var x = 0; x < full_playlist.length; x++){
var num = Math.floor(Math.random()*1000000);
full_playlist[x].added = num;
}
List.sortList();
List.populate_list(full_playlist);
}
},
get_admin:function() {
return [w_p, hasadmin];
for (var i = 0; i < names.length; i++) {
document.getElementsByName(names[i])[0].removeAttribute("disabled");
}
Helper.removeClass(".card-action", "hide");
Helper.addClass("#admin-lock", "clickable");
document.getElementById("admin-lock").innerHTML = "lock_open";
if (!Helper.mobilecheck()) {
Helper.tooltip("#admin-lock", {
delay: 5,
position: "left",
html: "Logout"
});
}
document.getElementById("password").value = "";
document
.getElementById("password")
.setAttribute("placeholder", "Change admin password");
Helper.removeClass(".user-password-li", "hide");
Helper.removeClass(".chat-toggle-li", "hide");
Helper.removeClass(".delete-all", "hide");
if (document.getElementsByClassName("password_protected")[0].checked) {
Helper.removeClass(".change_user_pass", "hide");
}
if (Helper.html("#admin-lock") != "lock_open") {
Helper.addClass("#admin-lock", "clickable");
document.getElementById("admin-lock").innerHTML = "lock_open";
if (!Helper.mobilecheck()) {
Helper.tooltip("#admin-lock", {
delay: 5,
position: "left",
html: "Logout"
});
}
}
},
hideUserSuggested: function() {
Helper.addClass("#user_suggests", "hide");
Helper.addClass("#user-suggest-html", "hide");
Helper.addClass(".suggested-badge", "hide");
},
conf: function(msg) {
if (msg[0].adminpass == "") {
////Crypt.remove_pass(chan.toLowerCase());
}
Admin.set_conf(msg[0]);
if (msg[0].adminpass !== "" && Admin.beginning) {
//emit("password", {password: Crypt.crypt_pass(Crypt.get_pass(chan.toLowerCase())), channel: chan.toLowerCase()});
Admin.beginning = false;
}
},
pass_save: function() {
if (!w_p) {
//emit('password', {password: Crypt.crypt_pass(CryptoJS.SHA256(document.getElementById("password").value).toString()), channel: chan.toLowerCase(), oldpass: Crypt.crypt_pass(Crypt.get_pass(chan.toLowerCase()))});
emit("password", {
password: Crypt.crypt_pass(document.getElementById("password").value),
channel: chan.toLowerCase()
});
} else {
//emit('password', {password: Crypt.crypt_pass(CryptoJS.SHA256(document.getElementById("password").value).toString()), channel: chan.toLowerCase()});
emit("password", {
password: Crypt.crypt_pass(document.getElementById("password").value),
channel: chan.toLowerCase()
});
}
},
log_out: function() {
before_toast();
/*if(Crypt.get_pass(chan.toLowerCase())) {*/
//Crypt.remove_pass(chan.toLowerCase());
if (Admin.logged_in) {
socket.emit("logout");
M.toast({ html: "Logged out", displayLength: 4000 });
Admin.display_logged_out();
} else {
M.toast({ html: "Not logged in", displayLength: 4000 });
}
},
display_logged_out: function() {
Admin.logged_in = false;
w_p = true;
adminpass = "";
names = [
"vote",
"addsongs",
"longsongs",
"frontpage",
"allvideos",
"removeplay",
"skip",
"shuffle",
"toggleChat",
"strictSkip"
];
document.getElementById("password").value = "";
Helper.addClass(".info_change_li", "hide");
for (i = 0; i < names.length; i++) {
document.getElementsByName(names[i])[0].setAttribute("disabled", true);
}
if (Helper.html("#admin-lock") != "lock") {
if (!Helper.mobilecheck()) {
Helper.tooltip("#admin-lock", "destroy");
}
Helper.removeClass("#admin-lock", "clickable");
document.getElementById("admin-lock").innerHTML = "lock";
}
Helper.addClass(".strict-skip-input", "hide");
Helper.addClass(".user-password-li", "hide");
Helper.addClass(".chat-toggle-li", "hide");
Helper.addClass(".delete-all", "hide");
if (document.getElementsByClassName("password_protected")[0].checked) {
Helper.removeClass(".change_user_pass", "hide");
}
Helper.addClass(".change_user_pass", "hide");
Admin.hideUserSuggested();
Helper.removeClass("#admin-lock", "clickable");
document
.getElementById("password")
.setAttribute("placeholder", "Enter admin password");
Helper.addClass(".delete-context-menu", "context-menu-disabled");
},
save: function(userpass) {
Admin.submitAdmin(
document.getElementById("adminSettingsForm").elements,
userpass
);
},
set_conf: function(conf_array) {
conf = conf_array;
music = conf_array.allvideos;
longsongs = conf_array.longsongs;
names = [
"vote",
"addsongs",
"longsongs",
"frontpage",
"allvideos",
"removeplay",
"skip",
"shuffle",
"userpass",
"toggleChat",
"strictSkip"
];
if (!conf.hasOwnProperty("toggleChat")) conf.toggleChat = true;
toggleChat = conf.toggleChat;
hasadmin = conf_array.adminpass != "";
var show_disabled = true;
if ((hasadmin && Admin.logged_in) || !hasadmin) {
show_disabled = false;
}
for (var i = 0; i < names.length; i++) {
document.getElementsByName(names[i])[0].checked =
conf_array[names[i]] === true;
if (show_disabled) {
document
.getElementsByName(names[i])[0]
.setAttribute("disabled", show_disabled);
} else {
document.getElementsByName(names[i])[0].removeAttribute("disabled");
}
}
document.getElementById("strict-input-number").value =
conf.strictSkipNumber;
if (hasadmin && !Admin.logged_in) {
if (Helper.html("#admin-lock") != "lock") Admin.display_logged_out();
} else if (!hasadmin) {
document
.getElementById("password")
.setAttribute("placeholder", "Create admin password");
} else {
if (document.getElementsByClassName("password_protected")[0].checked) {
Helper.removeClass(".change_user_pass", "hide");
}
}
if (Admin.logged_in) {
if (conf != undefined && conf.strictSkip) {
Helper.removeClass(".strict-skip-input", "hide");
}
}
if (conf != undefined && !conf.strictSkip) {
Helper.addClass(".strict-skip-input", "hide");
}
if (!document.getElementsByClassName("password_protected")[0].checked) {
Helper.addClass(".change_user_pass", "hide");
//Crypt.remove_userpass(chan.toLowerCase());
}
var updated = false;
if (conf_array.thumbnail != undefined && conf_array.thumbnail != "") {
document.getElementById("thumbnail_image").innerHTML =
"<img id='thumbnail_image_channel' src='" +
conf_array.thumbnail +
"' alt='thumbnail' />";
document.getElementById("thumbnail_input").value = conf_array.thumbnail;
updated = true;
}
if (conf_array.description != undefined && conf_array.description != "") {
document.getElementById("description_area").innerHTML =
conf_array.description;
document.getElementById("description_input").value =
conf_array.description;
updated = true;
}
if (conf_array.rules != undefined && conf_array.rules != "") {
var existingRules = document.querySelector(".rules-container");
if (existingRules) existingRules.remove();
var rules = conf_array.rules.split("\n");
var elementToAdd =
"<li class='rules-container'><div class='row'><div class='col s10 offset-s1'><h4 class='center-align'>Rules</h4>";
for (var i = 0; i < rules.length; i++) {
elementToAdd += "<p class='initial-line-height'>" + rules[i] + "</p>";
}
elementToAdd += "</div></div>";
document
.querySelector(".channel_info_container")
.insertAdjacentHTML("afterend", elementToAdd);
document.getElementById("rules_input").value = conf_array.rules;
updated = true;
}
if (updated) M.updateTextFields();
},
submitAdmin: function(form, userpass_changed) {
voting = form.vote.checked;
addsongs = form.addsongs.checked;
longsongs = form.longsongs.checked;
frontpage = form.frontpage.checked;
allvideos = form.allvideos.checked;
removeplay = form.removeplay.checked;
skipping = form.skip.checked;
shuffling = form.shuffle.checked;
toggleChat = form.toggleChat.checked;
strictSkip = form.strictSkip.checked;
if (form.strictSkipNumber) {
strictSkipNumber = form.strictSkipNumber;
} else {
strictSkipNumber = conf.strictSkipNumber;
}
var pass_send = userpass_changed && !form.userpass.checked ? "" : userpass;
configs = {
channel: chan.toLowerCase(),
voting: voting,
addsongs: addsongs,
longsongs: longsongs,
frontpage: frontpage,
allvideos: allvideos,
removeplay: removeplay,
adminpass: adminpass == "" ? "" : Crypt.crypt_pass(adminpass),
skipping: skipping,
shuffling: shuffling,
toggleChat: toggleChat,
strictSkip: strictSkip,
userpass: Crypt.crypt_pass(pass_send),
userpass_changed: userpass_changed,
strictSkipNumber: strictSkipNumber
};
emit("conf", configs);
},
hide_settings: function() {
var sidenavElem = document.getElementsByClassName("sidenav")[0];
M.Sidenav.getInstance(sidenavElem).close();
},
shuffle: function() {
if (!offline) {
//var u = Crypt.crypt_pass(Crypt.get_userpass(chan.toLowerCase()), true);
//if(u == undefined) u = "";
emit("shuffle", { channel: chan.toLowerCase() });
} else {
for (var x = 0; x < full_playlist.length; x++) {
var num = Math.floor(Math.random() * 1000000);
full_playlist[x].added = num;
}
List.sortList();
List.populate_list(full_playlist);
}
},
get_admin: function() {
return [w_p, hasadmin];
}
};

View File

@@ -1,40 +1,120 @@
window.addEventListener("load", function() {
var query = getQueryHash(window.location.hash);
var redirect = window.location.protocol + "//" + window.location.hostname + "/o_callback";
var client_id;
var response;
var scope;
var query = getQueryHash(window.location.hash);
var redirect =
window.location.protocol + "//" + window.location.hostname + "/api/oauth";
var client_id;
var response;
var scope;
if(query.spotify) {
client_id = "b934ecdd173648f5bcd38738af529d58";
response = "token";
scope = "playlist-read-private ugc-image-upload playlist-read-collaborative user-read-private playlist-modify-public playlist-modify-private";
state = query.nonce;
window.location.href = "https://accounts.spotify.com/authorize?client_id=" + client_id + "&scope=" + scope + "&show_dialog=false&response_type=" + response + "&redirect_uri=" + redirect + "&state=" + state;
if (query.spotify) {
client_id = "b934ecdd173648f5bcd38738af529d58";
response = "token";
scope =
"playlist-read-private ugc-image-upload playlist-read-collaborative user-read-private playlist-modify-public playlist-modify-private";
state = query.nonce;
window.location.href =
"https://accounts.spotify.com/authorize?client_id=" +
client_id +
"&scope=" +
scope +
"&show_dialog=false&response_type=" +
response +
"&redirect_uri=" +
redirect +
"&state=" +
state;
} else if (query.youtube) {
client_id =
"944988770273-butsmlr1aotlsskk8lmgvh0etqqekigf.apps.googleusercontent.com";
response = "token";
scope = "https://www.googleapis.com/auth/youtube";
state = query.nonce;
} else if (query.youtube) {
client_id = "944988770273-butsmlr1aotlsskk8lmgvh0etqqekigf.apps.googleusercontent.com";
response = "token";
scope = "https://www.googleapis.com/auth/youtube";
state = query.nonce;
//window.opener.callback(query);
window.location.href =
"https://accounts.google.com/o/oauth2/v2/auth?client_id=" +
client_id +
"&response_type=" +
response +
"&state=" +
state +
"&redirect_uri=" +
redirect +
"&scope=" +
scope;
} else if (query.soundcloud) {
/*
SC.initialize({
client_id: api_key.soundcloud,
redirect_uri: 'https://zoff.me/api/oauth'
});
//window.opener.callback(query);
window.location.href = "https://accounts.google.com/o/oauth2/v2/auth?client_id=" + client_id + "&response_type=" + response + "&state=" + state + "&redirect_uri=" + redirect + "&scope=" + scope;
// initiate auth popup
console.log("asd ok", api_key.soundcloud);
SC.connect().then(function() {
return SC.get('/me');
}).then(function(me) {
console.log(me);
//alert('Hello, ' + me.username);
}).catch(function(e) {
console.log(e);
});*/
var redirect_uri = encodeURIComponent("https://zoff.me/api/oauth");
var response_type = "code";
var scope = "non-expiring";
var state = query.nonce;
var url =
"https://soundcloud.com/connect?client_id=" +
api_key.soundcloud +
"&redirect_uri=" +
redirect_uri +
"&state=" +
state +
"&display=page&response_type=code&scope=" +
scope;
//console.log(url);
window.location.href = url;
} else {
var query_parameters;
if (window.location.search.length > 0) {
query_parameters = getQueryHash(window.location.search);
} else {
var query_parameters = getQueryHash(window.location.hash);
window.opener.callback(query_parameters);
query_parameters = getQueryHash(window.location.hash);
}
try {
window.opener.callback(query_parameters);
} catch (e) {
window.setTimeout(window.opener.SC_player.connectCallback, 1);
}
}
});
function getQueryHash(url) {
if (window.location.search.length > 0) {
if (url.substring(url.length - 1) == "#") {
url = url.substring(0, url.length - 1);
}
var temp_arr = url.substring(1).split("&");
var done_obj = {};
var splitted;
for(var i in temp_arr) {
splitted = temp_arr[i].split("=");
if(splitted.length == 2) {
done_obj[splitted[0]] = splitted[1];
}
for (var i in temp_arr) {
splitted = temp_arr[i].split("=");
if (splitted.length == 2) {
done_obj[splitted[0]] = splitted[1];
}
}
return done_obj;
} else {
var temp_arr = url.substring(1).split("&");
var done_obj = {};
var splitted;
for (var i in temp_arr) {
splitted = temp_arr[i].split("=");
if (splitted.length == 2) {
done_obj[splitted[0]] = splitted[1];
}
}
return done_obj;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,181 +1,311 @@
var Chat = {
channel_received: 0,
all_received: 0,
chat_admin_help: [
"/ban USERNAME REASON to ban user",
"/unban USERNAME to unban a user"
],
chat_help: [
"/login <new name> <password> to register and save a password for a nickname, or to log in with a password on a name.",
"/login <name> <new_password> <old_password> to change the password on a nickname",
"/logout to logout",
"/who to see the names of the people in the channel",
"Want your own icon besides your name? If you donate 5$ or more, we'll add a picture of your choosing (following our guidelines) besides your name!"
],
channel_received: 0,
all_received: 0,
chat_help: [
"/login <new name> <password> to register and save a password for a nickname, or to log in with a password on a name.",
"/login <name> <new_password> <old_password> to change the password on a nickname",
"/logout to logout",
"/who to see the names of the people in the channel"
],
namechange: function(data, first, initial) {
var input = data.split(" ");
if (input.length == 2) {
var name = input[0];
var password = input[1];
namechange: function(data, first, initial) {
var input = data.split(" ");
if(input.length == 2) {
var name = input[0];
var password = input[1];
password = Crypt.crypt_chat_pass(password);
socket.emit("namechange", {
name: name,
channel: chan.toLowerCase(),
password: password,
first: first
});
} else if (input.length == 3) {
var name = input[0];
var new_password = input[1];
var old_password = input[2];
password = Crypt.crypt_chat_pass(password);
socket.emit("namechange", {name: name, channel: chan.toLowerCase(), password: password, first: first});
} else if(input.length == 3) {
var name = input[0];
var new_password = input[1];
var old_password = input[2];
new_password = Crypt.crypt_chat_pass(new_password);
old_password = Crypt.crypt_chat_pass(old_password);
new_password = Crypt.crypt_chat_pass(new_password);
old_password = Crypt.crypt_chat_pass(old_password);
socket.emit("namechange", {name: name, channel: chan.toLowerCase(), new_password: new_password, old_password: old_password});
} else if(first) {
var to_send = {initial: initial, first: true};
if(chan != undefined && chan != "") {
to_send.channel = chan.toLowerCase();
}
socket.emit("namechange", to_send);
}
},
removename: function() {
socket.emit("removename", {channel: chan.toLowerCase()});
Crypt.remove_name();
},
chat: function(data) {
if(data.value.length > 150) return;
if(data.value.startsWith("/name ") || data.value.startsWith("/removename")) {
data.value = "/help";
Chat.chat(data);
return;
} else if(data.value.startsWith("/login ")){
Chat.namechange(data.value.substring(7), false);
} else if(data.value.startsWith("/help")) {
var add = "";
if(document.querySelector(".chat-tab-li a.active").getAttribute("href") == "#all_chat"){
if(document.querySelector("#chatall").children.length > 100) {
document.querySelector("#chatall").children[0].remove()
}
add = "chatall";
} else {
if(document.querySelector("#chatchannel").children.length > 100) {
document.querySelector("#chatchannel").children[0].remove()
}
add = "chatchannel";
}
for(var x = 0; x < Chat.chat_help.length; x++) {
var color = Helper.intToARGB(Helper.hashCode("System"));
if(color.length < 6) {
for(x = color.length; x < 6; x++) {
color = "0" + color;
}
}
var _time = new Date();
var time = Helper.pad(_time.getHours()) + ":" + Helper.pad(_time.getMinutes());
color = Helper.hexToRgb(color.substring(0,6));
var color_temp = Helper.rgbToHsl([color.r, color.g, color.b], false);
document.querySelector("#" + add).insertAdjacentHTML("beforeend", "<li title='Zoff''><span class='time_color'>" + time + "</span> <img class='chat-icon' src='https://zoff.me/assets/images/favicon-32x32.png' alt='System'><span style='color:" + color_temp + ";'>System</span>: </li>");
var in_text = document.createTextNode(Chat.chat_help[x]);
document.querySelector("#" + add).children[document.querySelector("#" + add).children.length - 1].appendChild(in_text);
document.getElementById("" + add).scrollTop = document.getElementById("" + add).scrollHeight;
}
} else if(data.value.startsWith("/logout")) {
Chat.removename();
} else if(document.querySelector(".chat-tab-li a.active").getAttribute("href") == "#all_chat") {
socket.emit("all,chat", {channel: chan.toLowerCase(), data: data.value});
} else {
socket.emit("chat", {channel: chan.toLowerCase(), data: data.value});
}
data.value = "";
return;
},
allchat: function(inp, time_sent, disable_blink) {
if(inp.msg.substring(0,1) == ":" && !chat_active && !disable_blink) {
Chat.all_received += 1;
document.querySelector("#favicon").getAttribute("href", "/assets/images/highlogo.png");
unseen = true;
chat_unseen = true;
Helper.removeClass(document.querySelector(".chat-link span.badge.new.white"), "hide");
var to_display = Chat.channel_received + Chat.all_received > 9 ? "9+" : Chat.channel_received + Chat.all_received;
Helper.setHtml(document.querySelector(".chat-link span.badge.new.white"), to_display);
}
if(document.hidden) {
document.getElementById("favicon").setAttribute("href", "/assets/images/highlogo.png");
}
if(document.querySelector("#chatall").children.length > 100) {
document.querySelector("#chatall").children[0].remove()
}
var color = Helper.intToARGB(Helper.hashCode(inp.from));
if(color.length < 6) {
for(x = color.length; x < 6; x++){
color = "0" + color;
}
}
var icon_add = "";
if(inp.hasOwnProperty("icon") && inp.icon !== false && inp.icon != "") {
icon_add = "<img class='chat-icon' src='" + inp.icon + "' alt='" + inp.from + "'>";
}
color = Helper.hexToRgb(color.substring(0,6));
var color_temp = Helper.rgbToHsl([color.r, color.g, color.b], false);
var _time = new Date();
if(time_sent) {
_time = new Date(time_sent);
}
var time = Helper.pad(_time.getHours()) + ":" + Helper.pad(_time.getMinutes());
document.querySelector("#chatall").insertAdjacentHTML("beforeend", "<li title='"+inp.channel+"'><span class='time_color'>" + time + "</span> " + icon_add + "<span style='color:"+color_temp+";'>"+inp.from+"</span><span class='channel-info-all-chat'> " + inp.channel + "</span></li>");
var in_text = document.createTextNode(inp.msg);
document.querySelector("#chatall").children[document.querySelector("#chatall").children.length - 1].appendChild(in_text);
if(!userscroll) {
programscroll = true;
document.getElementById("chatall").scrollTop = document.getElementById("chatall").scrollHeight;
programscroll = false;
}
},
channelchat: function(data, time_sent, disable_blink) {
if(data.msg.substring(0,1) == ":" && !chat_active && !disable_blink) {
document.querySelector("#favicon").setAttribute("href", "/assets/images/highlogo.png");
unseen = true;
chat_unseen = true;
Chat.channel_received += 1;
//blink_interval = setTimeout(Chat.chat_blink, 1000);
Helper.removeClass(document.querySelector(".chat-link span.badge.new.white"), "hide");
var to_display = Chat.channel_received + Chat.all_received > 9 ? "9+" : Chat.channel_received + Chat.all_received;
Helper.setHtml(document.querySelector(".chat-link span.badge.new.white"), to_display);
}
if(document.querySelector("#chatchannel").children.length > 100) {
document.querySelector("#chatchannel").children[0].remove()
}
var icon_add = "";
if(data.hasOwnProperty("icon") && data.icon !== false && data.icon != "") {
icon_add = "<img class='chat-icon' src='" + data.icon + "' alt='" + data.from + "'>";
}
var color = Helper.intToARGB(Helper.hashCode(data.from));
if(color.length < 6) {
for(x = color.length; x < 6; x++) {
color = "0" + color;
}
}
color = Helper.hexToRgb(color.substring(0,6));
var color_temp = Helper.rgbToHsl([color.r, color.g, color.b], false);
var _time = new Date();
if(time_sent) {
_time = new Date(time_sent);
}
var time = Helper.pad(_time.getHours()) + ":" + Helper.pad(_time.getMinutes());
document.querySelector("#chatchannel").insertAdjacentHTML("beforeend", "<li><span class='time_color'>" + time + "</span> " + icon_add + "<span style='color:"+color_temp+";'>"+data.from+"</span></li>");
var in_text = document.createTextNode(data.msg);
document.querySelector("#chatchannel").children[document.querySelector("#chatchannel").children.length - 1].appendChild(in_text);
if(!userscroll) {
programscroll = true;
document.getElementById("chatchannel").scrollTop = document.getElementById("chatchannel").scrollHeight;
programscroll = false;
}
socket.emit("namechange", {
name: name,
channel: chan.toLowerCase(),
new_password: new_password,
old_password: old_password
});
} else if (first) {
var to_send = { initial: initial, first: true };
if (chan != undefined && chan != "") {
to_send.channel = chan.toLowerCase();
}
socket.emit("namechange", to_send);
}
},
removename: function() {
socket.emit("removename", { channel: chan.toLowerCase() });
Crypt.remove_name();
},
chat: function(data) {
if (data.value.length > 150) return;
if (
data.value.startsWith("/name ") ||
data.value.startsWith("/removename")
) {
data.value = "/help";
Chat.chat(data);
return;
} else if (data.value.startsWith("/login ")) {
Chat.namechange(data.value.substring(7), false);
} else if (data.value.startsWith("/help")) {
var add = "";
if (
document.querySelector(".chat-tab-li a.active").getAttribute("href") ==
"#all_chat"
) {
if (document.querySelector("#chatall").children.length > 100) {
document.querySelector("#chatall").children[0].remove();
}
add = "chatall";
} else {
if (document.querySelector("#chatchannel").children.length > 100) {
document.querySelector("#chatchannel").children[0].remove();
}
add = "chatchannel";
}
var help = Chat.chat_help;
if (Admin.logged_in) help = help.concat(Chat.chat_admin_help);
for (var x = 0; x < help.length; x++) {
var color = Helper.intToARGB(Helper.hashCode("System"));
if (color.length < 6) {
for (x = color.length; x < 6; x++) {
color = "0" + color;
}
}
var _time = new Date();
var time =
Helper.pad(_time.getHours()) + ":" + Helper.pad(_time.getMinutes());
color = Helper.hexToRgb(color.substring(0, 6));
var color_temp = Helper.rgbToHsl([color.r, color.g, color.b], false);
document
.querySelector("#" + add)
.insertAdjacentHTML(
"beforeend",
"<li title='Zoff''><span class='time_color'>" +
time +
"</span> <img class='chat-icon' src='https://zoff.me/assets/images/favicon-32x32.png' alt='System'><span style='color:" +
color_temp +
";'>System</span>: </li>"
);
var in_text = document.createTextNode(help[x]);
document
.querySelector("#" + add)
.children[
document.querySelector("#" + add).children.length - 1
].appendChild(in_text);
document.getElementById("" + add).scrollTop = document.getElementById(
"" + add
).scrollHeight;
}
} else if (data.value.startsWith("/logout")) {
Chat.removename();
} else if (
document.querySelector(".chat-tab-li a.active").getAttribute("href") ==
"#all_chat"
) {
socket.emit("all,chat", {
channel: chan.toLowerCase(),
data: data.value
});
} else {
socket.emit("chat", { channel: chan.toLowerCase(), data: data.value });
}
data.value = "";
return;
},
createChatElement: function(
allchat,
channel,
time,
icon,
color,
from,
message
) {
var liElement = document.createElement("li");
liElement.innerHTML +=
"<span class='time_color'>" + time + "</span> " + icon;
var nameElement = document.createElement("span");
nameElement.innerText = from;
nameElement.style.color = color;
liElement.appendChild(nameElement);
if (allchat) {
liElement.title = channel;
liElement.innerHTML +=
"<span class='channel-info-all-chat'> " + channel + "</span>";
}
var in_text = document.createTextNode(message);
liElement.appendChild(in_text);
return liElement;
},
allchat: function(inp, time_sent, disable_blink) {
if (inp.msg.substring(0, 1) == ":" && !chat_active && !disable_blink) {
Chat.all_received += 1;
document
.querySelector("#favicon")
.getAttribute("href", "/assets/images/highlogo.png");
unseen = true;
chat_unseen = true;
Helper.removeClass(
document.querySelector(".chat-link span.badge.new.white"),
"hide"
);
var to_display =
Chat.channel_received + Chat.all_received > 9
? "9+"
: Chat.channel_received + Chat.all_received;
Helper.setHtml(
document.querySelector(".chat-link span.badge.new.white"),
to_display
);
}
if (document.hidden) {
document
.getElementById("favicon")
.setAttribute("href", "/assets/images/highlogo.png");
}
if (document.querySelector("#chatall").children.length > 100) {
document.querySelector("#chatall").children[0].remove();
}
var color = Helper.intToARGB(Helper.hashCode(inp.from));
if (color.length < 6) {
for (x = color.length; x < 6; x++) {
color = "0" + color;
}
}
var icon_add = "";
if (inp.hasOwnProperty("icon") && inp.icon !== false && inp.icon != "") {
icon_add =
"<img class='chat-icon' src='" + inp.icon + "' alt='" + inp.from + "'>";
}
color = Helper.hexToRgb(color.substring(0, 6));
var color_temp = Helper.rgbToHsl([color.r, color.g, color.b], false);
var _time = new Date();
if (time_sent) {
_time = new Date(time_sent);
}
var time =
Helper.pad(_time.getHours()) + ":" + Helper.pad(_time.getMinutes());
var element = Chat.createChatElement(
true,
Helper.decodeChannelName(inp.channel),
time,
icon_add,
color_temp,
inp.from,
inp.msg
);
//document.querySelector("#chatall").insertAdjacentHTML("beforeend", element);
document.querySelector("#chatall").appendChild(element);
if (!userscroll) {
programscroll = true;
document.getElementById("chatall").scrollTop = document.getElementById(
"chatall"
).scrollHeight;
programscroll = false;
}
},
channelchat: function(data, time_sent, disable_blink) {
if (
data.msg.substring(0, 1) == ":" &&
!chat_active &&
!disable_blink &&
data.from.toLowerCase() != "system"
) {
document
.querySelector("#favicon")
.setAttribute("href", "/assets/images/highlogo.png");
unseen = true;
chat_unseen = true;
Chat.channel_received += 1;
//blink_interval = setTimeout(Chat.chat_blink, 1000);
Helper.removeClass(
document.querySelector(".chat-link span.badge.new.white"),
"hide"
);
var to_display =
Chat.channel_received + Chat.all_received > 9
? "9+"
: Chat.channel_received + Chat.all_received;
Helper.setHtml(
document.querySelector(".chat-link span.badge.new.white"),
to_display
);
}
if (document.querySelector("#chatchannel").children.length > 100) {
document.querySelector("#chatchannel").children[0].remove();
}
var icon_add = "";
if (data.hasOwnProperty("icon") && data.icon !== false && data.icon != "") {
icon_add =
"<img class='chat-icon' src='" +
data.icon +
"' alt='" +
data.from +
"'>";
}
var color = Helper.intToARGB(Helper.hashCode(data.from));
if (color.length < 6) {
for (x = color.length; x < 6; x++) {
color = "0" + color;
}
}
color = Helper.hexToRgb(color.substring(0, 6));
var color_temp = Helper.rgbToHsl([color.r, color.g, color.b], false);
var _time = new Date();
if (time_sent) {
_time = new Date(time_sent);
}
var time =
Helper.pad(_time.getHours()) + ":" + Helper.pad(_time.getMinutes());
//document.querySelector("#chatchannel").insertAdjacentHTML("beforeend", "<li><span class='time_color'>" + time + "</span> " + icon_add + "<span style='color:"+color_temp+";'>"+data.from+"</span></li>");
//var in_text = document.createTextNode(data.msg);
//document.querySelector("#chatchannel").children[document.querySelector("#chatchannel").children.length - 1].appendChild(in_text);
var element = Chat.createChatElement(
false,
null,
time,
icon_add,
color_temp,
data.from,
data.msg
);
//document.querySelector("#chatall").insertAdjacentHTML("beforeend", element);
document.querySelector("#chatchannel").appendChild(element);
if (!userscroll) {
programscroll = true;
document.getElementById(
"chatchannel"
).scrollTop = document.getElementById("chatchannel").scrollHeight;
programscroll = false;
}
}
};

View File

@@ -1,38 +1,108 @@
var Crypt = {
conf_pass: undefined,
user_pass: undefined,
tmp_pass_user: "",
tmp_pass: "",
conf_pass: undefined,
user_pass: undefined,
tmp_pass_user: "",
tmp_pass: "",
init: function() {
if (window.location.pathname != "/") {
if (location.protocol != "https:") {
document.cookie =
chan.toLowerCase() +
"=;path=/" +
chan.toLowerCase() +
";expires=" +
new Date(0).toUTCString();
} else {
document.cookie =
chan.toLowerCase() +
"=;path=/" +
chan.toLowerCase() +
";secure;expires=" +
new Date(0).toUTCString();
}
}
init: function() {
try {
conf_arr = Crypt.decrypt(Crypt.getCookie("_opt"), "_opt");
} catch (err) {
conf_arr = Crypt.decrypt(Crypt.create_cookie("_opt"), "_opt");
}
if(window.location.pathname != "/") {
if (location.protocol != "https:") {
document.cookie = chan.toLowerCase() + '=;path=/' + chan.toLowerCase() + ';expires=' + new Date(0).toUTCString();
} else {
document.cookie = chan.toLowerCase() + '=;path=/' + chan.toLowerCase() + ';secure;expires=' + new Date(0).toUTCString();
}
if (window.location.pathname != "/") {
change_intelligent(Crypt.get_intelligent_list_enabled());
if (!conf_arr.hasOwnProperty("color")) {
Crypt.set_background_color("dynamic", true);
} else {
document.querySelector(".backround_switch_class").checked =
conf_arr.color == "dynamic";
if (conf_arr.color != "dynamic") {
Helper.removeClass(".background_color_container", "hide");
document.querySelector("#background_color_choser").value =
conf_arr.color;
}
}
Hostcontroller.change_enabled(conf_arr.remote);
if (conf_arr.width != 100) Player.set_width(conf_arr.width);
}
},
try {
conf_arr = Crypt.decrypt(Crypt.getCookie("_opt"), "_opt");
} catch(err) {
conf_arr = Crypt.decrypt(Crypt.create_cookie("_opt"), "_opt");
}
if(window.location.pathname != "/") {
Hostcontroller.change_enabled(conf_arr.remote);
if(conf_arr.width != 100) Player.set_width(conf_arr.width);
}
},
set_background_color: function(value, first) {
conf_arr.color = value;
if (value != "dynamic" && !first) {
Helper.css("#main-container", "background-color", value);
Helper.css("#nav", "background-color", value);
Helper.css(".title-container", "background-color", value);
document
.querySelector("meta[name=theme-color]")
.setAttribute("content", value);
Helper.css("#controls", "background", value);
} else if (!first) {
var url = "https://img.youtube.com/vi/" + Player.np.id + "/mqdefault.jpg";
if (videoSource == "soundcloud") url = Player.np.thumbnail;
getColor(url);
}
Crypt.encrypt(conf_arr, "_opt");
},
decrypt: function(cookie, name) {
if(Crypt.getCookie(name) === undefined) {
cookie = Crypt.create_cookie(name);
}
if(cookie == undefined && name == "_opt") return {"volume":100,"width":100,"remote":true,"name":"","offline":false};
/*var key = btoa("0103060703080703080701") + btoa("0103060703080703080701");
get_background_color: function(value) {
if (!conf_arr.hasOwnProperty("color")) {
Crypt.set_background_color("dynamic");
}
return conf_arr.color;
},
get_intelligent_list_enabled: function() {
if (conf_arr.hasOwnProperty("intelligent")) {
return conf_arr.intelligent;
} else {
conf_arr.intelligent = false;
Crypt.encrypt(conf_arr, "_opt");
return false;
}
},
set_intelligent_list_enabled: function(enabled) {
conf_arr.intelligent = enabled;
if (Helper.mobilecheck()) {
intelligentList = enabled;
}
Crypt.encrypt(conf_arr, "_opt");
},
decrypt: function(cookie, name) {
if (Crypt.getCookie(name) === undefined) {
cookie = Crypt.create_cookie(name);
}
if (cookie == undefined && name == "_opt")
return {
volume: 100,
width: 100,
remote: true,
name: "",
offline: false
};
/*var key = btoa("0103060703080703080701") + btoa("0103060703080703080701");
key = key.substring(0,32);
key = btoa(key);
var decrypted = CryptoJS.AES.decrypt(
@@ -43,13 +113,13 @@ var Crypt = {
}
);*/
//return $.parseJSON(decrypted.toString(CryptoJS.enc.Utf8));
return JSON.parse(atob(cookie));
},
//return $.parseJSON(decrypted.toString(CryptoJS.enc.Utf8));
return JSON.parse(atob(cookie));
},
decrypt_pass: function(pass) {
if(socket) {
/*var key = btoa(socket.id) + btoa(socket.id);
decrypt_pass: function(pass) {
if (socket) {
/*var key = btoa(socket.id) + btoa(socket.id);
key = key.substring(0,32);
key = btoa(key);
var decrypted = CryptoJS.AES.decrypt(
@@ -60,13 +130,14 @@ var Crypt = {
}
);
return decrypted.toString(CryptoJS.enc.Utf8);*/
return atob(pass);
} return false;
},
return atob(pass);
}
return false;
},
encrypt: function(json_formated, cookie) {
var to_encrypt = JSON.stringify(json_formated);
/*var key = btoa("0103060703080703080701") + btoa("0103060703080703080701");
encrypt: function(json_formated, cookie) {
var to_encrypt = JSON.stringify(json_formated);
/*var key = btoa("0103060703080703080701") + btoa("0103060703080703080701");
key = key.substring(0,32);
key = btoa(key);
var encrypted = CryptoJS.AES.encrypt(
@@ -77,42 +148,61 @@ var Crypt = {
padding: CryptoJS.pad.Pkcs7
}
);*/
var encrypted = btoa(to_encrypt);
var CookieDate = new Date();
CookieDate.setFullYear(CookieDate.getFullYear( ) +1);
if (location.protocol != "https:"){
document.cookie = cookie+"="+encrypted.toString()+";expires="+CookieDate.toGMTString()+";path=/;";
} else {
document.cookie = cookie+"="+encrypted.toString()+";secure;expires="+CookieDate.toGMTString()+";path=/;";
}
},
var encrypted = btoa(to_encrypt);
var CookieDate = new Date();
CookieDate.setFullYear(CookieDate.getFullYear() + 1);
if (location.protocol != "https:") {
document.cookie =
cookie +
"=" +
encrypted.toString() +
";expires=" +
CookieDate.toGMTString() +
";path=/;";
} else {
document.cookie =
cookie +
"=" +
encrypted.toString() +
";secure;expires=" +
CookieDate.toGMTString() +
";path=/;";
}
},
get_volume: function() {
return Crypt.decrypt(Crypt.getCookie("_opt"), "_opt").volume;
//return conf_arr.volume;
},
get_volume: function() {
return Crypt.decrypt(Crypt.getCookie("_opt"), "_opt").volume;
//return conf_arr.volume;
},
get_offline: function() {
var temp_offline = Crypt.decrypt(Crypt.getCookie("_opt"), "_opt").offline;
if(temp_offline != undefined){
return Crypt.decrypt(Crypt.getCookie("_opt"), "_opt").offline;
} else {
Crypt.set_offline(false);
return false;
}
},
get_offline: function() {
var temp_offline = Crypt.decrypt(Crypt.getCookie("_opt"), "_opt").offline;
if (temp_offline != undefined) {
return Crypt.decrypt(Crypt.getCookie("_opt"), "_opt").offline;
} else {
Crypt.set_offline(false);
return false;
}
},
set_volume: function(val) {
conf_arr.volume = val;
Crypt.encrypt(conf_arr, "_opt");
},
set_volume: function(val) {
conf_arr.volume = val;
Crypt.encrypt(conf_arr, "_opt");
},
create_cookie: function(name) {
if(name == "_opt") cookie_object = {volume: 100, width: 100, remote: true, name: "", offline: false};
else cookie_object = {passwords: {}};
create_cookie: function(name) {
if (name == "_opt")
cookie_object = {
volume: 100,
width: 100,
remote: true,
name: "",
offline: false
};
else cookie_object = { passwords: {} };
var string_it = JSON.stringify(cookie_object);
/*var key = btoa("0103060703080703080701") + btoa("0103060703080703080701");
var string_it = JSON.stringify(cookie_object);
/*var key = btoa("0103060703080703080701") + btoa("0103060703080703080701");
key = key.substring(0,32);
key = btoa(key);
var encrypted = CryptoJS.AES.encrypt(
@@ -123,22 +213,34 @@ var Crypt = {
padding: CryptoJS.pad.Pkcs7
}
);*/
var encrypted = btoa(string_it);
var encrypted = btoa(string_it);
var CookieDate = new Date();
CookieDate.setFullYear(CookieDate.getFullYear( ) +1);
var CookieDate = new Date();
CookieDate.setFullYear(CookieDate.getFullYear() + 1);
if (location.protocol != "https:"){
document.cookie = name+"="+encrypted.toString()+";expires="+CookieDate.toGMTString()+";path=/;";
} else {
document.cookie = name+"="+encrypted.toString()+";secure;expires="+CookieDate.toGMTString()+";path=/;";
}
//document.cookie = name+"="+encrypted.toString()+";expires="+CookieDate.toGMTString()+";path=/;"
//document.cookie = na"="+encrypted.toString()+";expires="+CookieDate.toGMTString()+";path=/;"
return Crypt.getCookie(name);
},
if (location.protocol != "https:") {
document.cookie =
name +
"=" +
encrypted.toString() +
";expires=" +
CookieDate.toGMTString() +
";path=/;";
} else {
document.cookie =
name +
"=" +
encrypted.toString() +
";secure;expires=" +
CookieDate.toGMTString() +
";path=/;";
}
//document.cookie = name+"="+encrypted.toString()+";expires="+CookieDate.toGMTString()+";path=/;"
//document.cookie = na"="+encrypted.toString()+";expires="+CookieDate.toGMTString()+";path=/;"
return Crypt.getCookie(name);
},
/*set_pass: function(chan, pass) {
/*set_pass: function(chan, pass) {
Crypt.conf_pass.passwords[chan] = pass;
Crypt.encrypt(Crypt.conf_pass, chan);
},
@@ -158,44 +260,45 @@ var Crypt = {
Crypt.encrypt(Crypt.conf_pass, chan.toLowerCase());
},*/
set_name:function(name, pass) {
conf_arr.name = encodeURIComponent(name).replace(/\W/g, '');
conf_arr.chat_pass = pass;
Crypt.encrypt(conf_arr, "_opt");
},
set_name: function(name, pass) {
conf_arr.name = encodeURIComponent(name).replace(/\W/g, "");
conf_arr.chat_pass = pass;
Crypt.encrypt(conf_arr, "_opt");
},
set_offline: function(enabled) {
conf_arr.offline = enabled;
Crypt.encrypt(conf_arr, "_opt");
},
set_offline: function(enabled) {
conf_arr.offline = enabled;
Crypt.encrypt(conf_arr, "_opt");
},
remove_name:function() {
conf_arr.name = "";
conf_arr.chat_pass = "";
Crypt.encrypt(conf_arr, "_opt");
},
remove_name: function() {
conf_arr.name = "";
conf_arr.chat_pass = "";
Crypt.encrypt(conf_arr, "_opt");
},
get_pass: function(chan) {
if(Crypt.conf_pass !== undefined) return Crypt.conf_pass.passwords[chan];
return undefined;
},
get_pass: function(chan) {
if (Crypt.conf_pass !== undefined) return Crypt.conf_pass.passwords[chan];
return undefined;
},
get_userpass: function(chan) {
if(Crypt.conf_pass !== undefined) return Crypt.conf_pass.passwords["userpass"];
return "";
},
get_userpass: function(chan) {
if (Crypt.conf_pass !== undefined)
return Crypt.conf_pass.passwords["userpass"];
return "";
},
set_remote: function(val) {
conf_arr.remote = val;
Crypt.encrypt(conf_arr, "_opt");
},
set_remote: function(val) {
conf_arr.remote = val;
Crypt.encrypt(conf_arr, "_opt");
},
get_remote: function(val) {
return conf_arr.remote;
},
get_remote: function(val) {
return conf_arr.remote;
},
crypt_chat_pass: function(pass) {
/*var key = btoa(socket.id) + btoa(socket.id);
crypt_chat_pass: function(pass) {
/*var key = btoa(socket.id) + btoa(socket.id);
key = key.substring(0,32);
key = btoa(key);
var iv = btoa(Crypt.makeiv());
@@ -208,43 +311,48 @@ var Crypt = {
iv: CryptoJS.enc.Base64.parse(iv),
}
);*/
//window.encrypted = encrypted;
return btoa(pass);
//return encrypted.toString() + "$" + iv;
},
//window.encrypted = encrypted;
return btoa(pass);
//return encrypted.toString() + "$" + iv;
},
crypt_pass: function(pass, userpass) {
if(userpass) {
Crypt.tmp_pass_user = pass;
} else {
Crypt.tmp_pass = pass;
}
//return Crypt.crypt_chat_pass(pass);
return btoa(pass);
},
makeiv: function() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 16; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
},
get_width: function() {
return conf_arr.width;
},
set_width: function(val) {
conf_arr.width = val;
Crypt.encrypt(conf_arr, "_opt");
},
getCookie: function(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
crypt_pass: function(pass, userpass) {
if (userpass) {
Crypt.tmp_pass_user = pass;
} else {
Crypt.tmp_pass = pass;
}
//return Crypt.crypt_chat_pass(pass);
return btoa(pass);
},
makeiv: function() {
var text = "";
var possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 16; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
},
get_width: function() {
return conf_arr.width;
},
set_width: function(val) {
conf_arr.width = val;
Crypt.encrypt(conf_arr, "_opt");
},
getCookie: function(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2)
return parts
.pop()
.split(";")
.shift();
}
};

View File

@@ -3,16 +3,34 @@ var timed_remove_check;
var gotten_np = false;
var song_title = "";
var paused = false;
var intelligentList = false;
var client = false;
var _VERSION;
try {
_VERSION = localStorage.getItem("VERSION");
if(_VERSION == null || _VERSION == undefined) throw "Some error";
} catch(e) {
_VERSION = 6;
_VERSION = localStorage.getItem("VERSION");
if (_VERSION == null || _VERSION == undefined) throw "Some error";
} catch (e) {
_VERSION = 6;
}
var SC_widget;
var scUsingWidget = false;
var zoff_api_token = "DwpnKVkaMH2HdcpJT2YPy783SY33byF5/32rbs0+xdU=";
if (
window.location.hostname == "localhost" ||
window.location.hostname == "client.localhost"
) {
var zoff_api_token = "AhmC4Yg2BhaWPZBXeoWK96DAiAVfbou8TUG2IXtD3ZQ=";
}
var SC_player;
var durationTimeout;
var intelligentQueue = [];
var deleted_elements = 0;
var sc_need_initialization = true;
var sc_initialized = false;
var startTime = 0;
var full_playlist;
var small = false;
var small_player = false;
var full_playlist = [];
var hostMode = false;
var soundcloud_enabled = true;
var socket_connected = false;
@@ -28,11 +46,11 @@ var beginning = false;
var soundcloud_loading = false;
var videoSource = "";
var list_html = document.getElementById("list-song-html").innerHTML;
var w_p = true;
var lazy_load = false;
var w_p = true;
var lazy_load = false;
var end_programmatically = false;
var embed = true;
var vol = 100;
var vol = 100;
var adminpass = "";
var mobile_beginning = false;
var durationBegun = false;
@@ -44,417 +62,473 @@ var began = false;
var seekTo;
var socket;
var video_id;
var hash = window.location.hash.substring(1).split("&");
var chan = hash[0];
var autoplay = false;
var color = "#808080";
var embedOptions = getSearch(window.location.search);
var chan = Helper.decodeChannelName(embedOptions["channel"]);
var autoplay = embedOptions["autoplay"];
var videoonly = embedOptions["videoonly"];
var color = "#" + embedOptions["color"];
var localmode = embedOptions["localmode"];
var dragging = false;
var user_auth_started = false;
var user_auth_avoid = false;
var connection_options = {
'sync disconnect on unload':true,
'secure': true,
'force new connection': true
"sync disconnect on unload": true,
secure: true,
"force new connection": true
};
var Crypt = {
crypt_pass: function(pass) {
return pass;
}
crypt_pass: function(pass) {
return pass;
},
get_background_color: function() {
return "dynamic";
}
};
function receiveMessage(event) {
if(event.data == "parent") {
window.parentWindow = event.source;
window.parentOrigin = event.origin;
}
if(event.data == "lower") {
window.setVolume(10);
}else if(event.data == "reset") {
window.setVolume(100);
} else if(event.data == "get_info") {
window.parentWindow.postMessage({type: "np", title: song_title}, window.parentOrigin);
window.parentWindow.postMessage({type: "controller", id: Hostcontroller.old_id}, window.parentOrigin);
if(full_playlist.length > 0) {
Player.sendNext({title: full_playlist[0].title, videoId: full_playlist[0].id});
}
}
if (event.data == "parent") {
window.parentWindow = event.source;
window.parentOrigin = event.origin;
}
if (event.data == "lower") {
window.setVolume(10);
} else if (event.data == "reset") {
window.setVolume(100);
} else if (event.data == "get_info") {
window.parentWindow.postMessage(
{ type: "np", title: song_title },
window.parentOrigin
);
window.parentWindow.postMessage(
{ type: "controller", id: Hostcontroller.old_id },
window.parentOrigin
);
try {
if (full_playlist.length > 0) {
Player.sendNext({
title: full_playlist[0].title,
videoId: full_playlist[0].id
});
}
} catch (e) {}
}
}
window.addEventListener("message", receiveMessage, false);
window.addEventListener("DOMContentLoaded", function() {
});
window.addEventListener("DOMContentLoaded", function() {});
var Channel = {
set_title_width: function() {},
window_width_volume_slider: function() {}
};
function getSearch(elem) {
var result = {};
var search = window.location.search.split("&");
for (var i = 0; i < search.length; i++) {
var currElement = search[i].split("=");
var key = currElement[0].replace("?", "");
var value = currElement[1];
if (value == "true") value = true;
else if (value == "false") value = false;
result[key] = value;
}
return result;
}
window.addEventListener("load", function() {
if(hash.length >= 2 && hash.indexOf("autoplay") > 0){
autoplay = true;
Helper.css("#player", "visibility", "hidden");
} else {
//paused = true;
}
if(hash.indexOf("videoonly") > -1) {
Helper.addClass("#wrapper", "hide");
Helper.addClass("#controls", "hide");
Helper.addClass("#player", "video_only");
Helper.addClass("#player_overlay", "video_only");
Helper.css("#zoffbutton", "bottom", "0px");
if (autoplay) {
Helper.css("#player", "visibility", "hidden");
}
if (videoonly) {
Helper.addClass("#wrapper", "hide");
Helper.addClass("#controls", "hide");
Helper.addClass("#player", "video_only");
Helper.addClass("#player_overlay", "video_only");
Helper.css("#zoffbutton", "bottom", "0px");
Helper.css("#song-title", "width", "100vw");
}
M.Modal.init(document.getElementById("locked_channel"), {
dismissible: false
});
add = "https://zoff.me";
//if(window.location.hostname == "localhost") add = "localhost";
//add = "localhost";
socket = io.connect(
"" + add,
connection_options
);
if (localmode) {
change_offline(true, false);
}
socket.on("auth_required", function() {
M.Modal.getInstance(document.getElementById("locked_channel")).open();
});
document.querySelector(".channel-info-container").href =
"https://zoff.me/" + chan.toLowerCase();
document.querySelector(".channel-title").innerText = "/" + chan.toLowerCase();
socket.on("get_list", function() {
socket_connected = true;
setTimeout(function() {
socket.emit("list", {
version: VERSION,
channel: chan.toLowerCase(),
pass: ""
});
}, 1000);
});
socket.on("self_ping", function() {
if (chan != undefined && chan.toLowerCase() != "") {
socket.emit("self_ping", { channel: chan.toLowerCase() });
}
});
M.Modal.init(document.getElementById("locked_channel"), {
dismissible: false
});
color = "#" + hash[1];
add = "https://zoff.me";
//if(window.location.hostname == "localhost") add = "localhost";
//add = "localhost";
socket = io.connect(''+add+':8080', connection_options);
socket.on("viewers", function(view) {
viewers = view;
if(hash.indexOf("localmode") > 1) {
change_offline(true, false);
}
if (song_title !== undefined) Player.getTitle(song_title, viewers);
});
socket.on('auth_required', function() {
M.Modal.getInstance(document.getElementById("locked_channel")).open();
});
Player.loadPlayer();
setup_host_initialization();
setup_now_playing_listener();
setup_list_listener();
socket.on("get_list", function() {
setTimeout(function(){socket.emit('list', {version: VERSION, channel: chan.toLowerCase(), pass: ''});},1000);
});
if (autoplay) {
startWaitTimerPlay();
}
socket.on("self_ping", function() {
if(chan != undefined && chan.toLowerCase() != "") {
socket.emit("self_ping", {channel: chan.toLowerCase()});
}
});
List.calculate_song_heights();
socket.on("viewers", function(view) {
viewers = view;
window.onYouTubeIframeAPIReady = Player.onYouTubeIframeAPIReady;
socket.on("toast", toast);
if(song_title !== undefined)
Player.getTitle(song_title, viewers);
});
Playercontrols.initSlider();
document
.getElementById("playpause")
.addEventListener("click", Playercontrols.play_pause);
window.setVolume = setVolume;
//Helper.css("#controls", "background-color", color);
Player.loadPlayer();
setup_host_initialization();
setup_now_playing_listener();
setup_list_listener();
if(autoplay) {
startWaitTimerPlay();
}
List.calculate_song_heights();
window.onYouTubeIframeAPIReady = Player.onYouTubeIframeAPIReady;
socket.on("toast", toast);
Playercontrols.initSlider();
document.getElementById("playpause").addEventListener("click", Playercontrols.play_pause);
window.setVolume = setVolume;
//Helper.css("#controls", "background-color", color);
document.querySelector("body").style.backgroundColor = color;
if(hash.indexOf("controll") > -1) {
Hostcontroller.change_enabled(true);
} else {
Hostcontroller.change_enabled(false);
}
document.querySelector("body").style.backgroundColor = color;
if (embedOptions.hasOwnProperty("control") && embedOptions.control) {
Hostcontroller.change_enabled(true);
} else {
Hostcontroller.change_enabled(false);
}
});
function resizePlaylistPlaying(){};
window.addEventListener("resize", function() {
resizeFunction();
});
function resizePlaylistPlaying() {}
function startWaitTimerPlay() {
setTimeout(function() {
if(videoSource == "youtube") {
Player.player.playVideo();
} else if(videoSource == "soundcloud"){
Player.soundcloud_player.play();
}
}, 5000);
setTimeout(function() {
if (videoSource == "youtube") {
Player.player.playVideo();
} else if (videoSource == "soundcloud") {
Player.soundcloud_player.play();
}
}, 5000);
}
function setup_host_listener(id) {
socket.on(id, Hostcontroller.host_on_action);
socket.on(id, Hostcontroller.host_on_action);
}
function setup_host_initialization() {
socket.on("id", Hostcontroller.host_listener);
socket.on("id", Hostcontroller.host_listener);
}
function setup_now_playing_listener() {
socket.on("np", Player.now_playing_listener);
socket.on("np", Player.now_playing_listener);
}
function setup_list_listener() {
socket.on("channel", List.channel_function);
socket.on("channel", function(msg) {
Helper.addClass(".site_loader", "hide");
List.channel_function(msg);
});
}
function setVolume(val) {
Playercontrols.visualVolume(val);
Playercontrols.setVolume(val);
Playercontrols.visualVolume(val);
Playercontrols.setVolume(val);
}
function updateChromecastMetadata(){}
function loadChromecastVideo(){}
function updateChromecastMetadata() {}
function loadChromecastVideo() {}
function toast(msg) {
switch(msg) {
case "suggested_thumbnail":
if(embed) return;
msg = "The thumbnail has been suggested!";
break;
case "faulty_start_end":
if(embed) return;
break;
case "wait_longer":
if(embed) return;
break;
case "suggested_description":
if(embed) return;
break;
case "thumbnail_denied":
if(embed) return;
break;
case "description_denied":
if(embed) return;
break;
case "addedsong":
if(embed) return;
break;
case "addedplaylist":
if(embed) return;
break;
case "savedsettings":
if(embed) return;
break;
case "wrongpass":
if(embed) return;
break;
case "deleted_songs":
if(embed) return;
break;
case "shuffled":
if(embed) return;
break;
case "deletesong":
if(embed) return;
break;
case "voted":
msg=Helper.rnd(["You voted!", "You vote like a boss", "Voting is the key to democracy", "May you get your song to the very top!", "I love that song! I vouch for you.", "Only you vote that good", "I like the way you vote...", "Up the video goes!", "Voted Zoff for president", "Only 999 more to go!"]);
break;
case "alreadyvoted":
msg=Helper.rnd(["You can't vote twice on that song!", "I see you have voted on that song before", "One vote per person!", "I know you want to hear your song, but have patience!", "I'm sorry, but I can't let you vote twice, Dave."]);
break;
case "skip":
if(embed) return;
break;
case "listhaspass":
if(embed) return;
break;
case "noskip":
if(embed) return;
break;
case "alreadyskip":
if(embed) return;
break;
case "notyetskip":
if(embed) return;
break;
case "correctpass":
if(embed) return;
break;
case "changedpass":
if(embed) return;
break;
case "suggested":
if(embed) return;
break;
case "alreadyplay":
if(embed) return;
break;
}
before_toast();
M.toast({html: msg, displayLength: 4000});
switch (msg) {
case "suggested_thumbnail":
if (embed) return;
msg = "The thumbnail has been suggested!";
break;
case "faulty_start_end":
if (embed) return;
break;
case "wait_longer":
if (embed) return;
break;
case "suggested_description":
if (embed) return;
break;
case "thumbnail_denied":
if (embed) return;
break;
case "description_denied":
if (embed) return;
break;
case "addedsong":
if (embed) return;
break;
case "addedplaylist":
if (embed) return;
break;
case "savedsettings":
if (embed) return;
break;
case "wrongpass":
if (embed) return;
break;
case "deleted_songs":
if (embed) return;
break;
case "shuffled":
if (embed) return;
break;
case "deletesong":
if (embed) return;
break;
case "voted":
msg = Helper.rnd([
"You voted!",
"You vote like a boss",
"Voting is the key to democracy",
"May you get your song to the very top!",
"I love that song! I vouch for you.",
"Only you vote that good",
"I like the way you vote...",
"Up the video goes!",
"Voted Zoff for president",
"Only 999 more to go!"
]);
break;
case "alreadyvoted":
msg = Helper.rnd([
"You can't vote twice on that song!",
"I see you have voted on that song before",
"One vote per person!",
"I know you want to hear your song, but have patience!",
"I'm sorry, but I can't let you vote twice, Dave."
]);
break;
case "skip":
if (embed) return;
break;
case "listhaspass":
if (embed) return;
break;
case "noskip":
if (embed) return;
break;
case "alreadyskip":
if (embed) return;
break;
case "notyetskip":
if (embed) return;
break;
case "correctpass":
if (embed) return;
break;
case "changedpass":
if (embed) return;
break;
case "suggested":
if (embed) return;
break;
case "alreadyplay":
if (embed) return;
break;
}
before_toast();
M.toast({ html: msg, displayLength: 4000 });
}
function emit() {
if(!embed) {
lastCommand = [];
for(var i = 0; i < arguments.length; i++) {
lastCommand.push(arguments[i]);
}
}
if(arguments.length == 1) {
socket.emit(arguments[0]);
} else {
socket.emit(arguments[0], arguments[1]);
if (!embed) {
lastCommand = [];
for (var i = 0; i < arguments.length; i++) {
lastCommand.push(arguments[i]);
}
}
if (arguments.length == 1) {
socket.emit(arguments[0]);
} else {
socket.emit(arguments[0], arguments[1]);
}
}
function change_offline(enabled, already_offline){
if(client) {
offline = false;
return;
function change_offline(enabled, already_offline) {
offline = enabled;
socket.emit("offline", {
status: enabled,
channel: chan != undefined ? chan.toLowerCase() : ""
});
if (!Helper.mobilecheck()) {
if (
document.querySelectorAll("#offline-mode").length == 1 &&
M.Tooltip.getInstance(document.getElementById("offline-mode"))
) {
Helper.tooltip("#offline-mode", "destroy");
}
offline = enabled;
socket.emit("offline", {status: enabled, channel: chan != undefined ? chan.toLowerCase() : ""});
if(!Helper.mobilecheck()) {
if(document.querySelectorAll("#offline-mode").length == 1 && M.Tooltip.getInstance(document.getElementById("offline-mode"))) {
Helper.tooltip("#offline-mode", 'destroy');
}
}
var mouseEnter = function(e) {
Helper.removeClass("#seekToDuration", "hide");
};
var mouseLeave = function(e) {
dragging = false;
Helper.addClass("#seekToDuration", "hide");
};
var mouseDown = function(e) {
var acceptable = ["bar", "controls", "duration"];
if (acceptable.indexOf(e.target.id) >= 0) {
dragging = true;
}
};
var mouseEnter = function(e){
Helper.removeClass("#seekToDuration", "hide");
};
var mouseUp = function(e) {
dragging = false;
};
if (enabled) {
Helper.addClass("#viewers", "hide");
Helper.removeClass(".margin-playbar", "margin-playbar");
Helper.addClass(".prev playbar", "margin-playbar");
Helper.removeClass(".prev playbar", "hide");
var mouseLeave = function(e){
dragging = false;
Helper.addClass("#seekToDuration", "hide");
};
if (window.location.pathname != "/") {
document
.getElementById("controls")
.addEventListener("mouseenter", mouseEnter, false);
document
.getElementById("controls")
.addEventListener("mouseleave", mouseLeave, false);
document
.getElementById("controls")
.addEventListener("mousedown", mouseDown, false);
document
.getElementById("controls")
.addEventListener("mouseup", mouseUp, false);
document
.getElementById("controls")
.addEventListener("mousemove", seekToMove);
document
.getElementById("controls")
.addEventListener("click", seekToClick);
var mouseDown = function(e) {
var acceptable = ["bar", "controls", "duration"];
if(acceptable.indexOf(e.target.id) >= 0) {
dragging = true;
}
};
var mouseUp = function(e) {
dragging = false;
};
if(enabled){
Helper.addClass("#viewers", "hide");
Helper.removeClass(".margin-playbar", "margin-playbar");
Helper.addClass(".prev playbar", "margin-playbar");
Helper.removeClass(".prev playbar", "hide");
Helper.removeClass(".skip playbar", "hide");
Helper.removeClass("#offline-mode", "waves-cyan");
Helper.addClass("#offline-mode", "cyan");
Helper.removeClass(".delete-context-menu", "context-menu-disabled");
if(!Helper.mobilecheck()) {
Helper.tooltip("#offline-mode", {
delay: 5,
position: "bottom",
html: "Disable local mode"
});
}
if(window.location.pathname != "/"){
socket.removeEventListener("color");
document.getElementById("controls").addEventListener("mouseenter", mouseEnter, false);
document.getElementById("controls").addEventListener("mouseleave", mouseLeave, false);
document.getElementById("controls").addEventListener("mousedown", mouseDown, false);
document.getElementById("controls").addEventListener("mouseup", mouseUp, false);
document.getElementById("controls").addEventListener("mousemove", seekToMove);
document.getElementById("controls").addEventListener("click", seekToClick);
document.querySelector("#main_components").insertAdjacentHTML("beforeend", "<div id='seekToDuration' class='hide'>00:00/01:00</div>");
var controlElement = document.querySelector("#controls");
Helper.css("#seekToDuration", "bottom", "50px");
Helper.addClass("#controls", "ewresize");
}
if(full_playlist != undefined && !already_offline){
for(var x = 0; x < full_playlist.length; x++){
full_playlist[x].votes = 0;
}
List.sortList();
List.populate_list(full_playlist);
}
} else {
if(!Admin.logged_in) Helper.addClass(".delete-context-menu", "context-menu-disabled");
Helper.removeClass(".margin-playbar", "margin-playbar");
Helper.addClass("#playpause", "margin-playbar");
Helper.removeClass("#viewers", "hide");
Helper.addClass(".prev playbar", "hide");
Helper.addClass(".skip playbar", "hide");
Helper.addClass("#offline-mode", "waves-cyan");
Helper.removeClass("#offline-mode", "cyan");
if(!Helper.mobilecheck()) {
Helper.tooltip("#offline-mode", {
delay: 5,
position: "bottom",
html: "Enable local mode"
});
}
if(window.location.pathname != "/"){
document.getElementById("controls").removeEventListener("mouseenter", mouseEnter, false);
document.getElementById("controls").removeEventListener("mouseleave", mouseLeave, false);
document.getElementById("controls").removeEventListener("mousedown", mouseDown, false);
document.getElementById("controls").removeEventListener("mouseup", mouseUp, false);
document.getElementById("controls").removeEventListener("mousemove", seekToMove);
document.getElementById("controls").removeEventListener("click", seekToClick);
Helper.removeElement("#seekToDuration");
socket.on("color", Player.setBGimage);
socket.emit("pos", {channel: chan.toLowerCase()});
var add = "";
//if(private_channel) add = Crypt.getCookie("_uI") + "_";
socket.emit("list", {version: parseInt(_VERSION), channel: add + chan.toLowerCase()});
Helper.removeClass("#controls", "ewresize");
}
document
.querySelector("#main_components")
.insertAdjacentHTML(
"beforeend",
"<div id='seekToDuration' class='hide'>00:00/01:00</div>"
);
var controlElement = document.querySelector("#controls");
Helper.css("#seekToDuration", "bottom", "50px");
Helper.addClass("#controls", "ewresize");
}
if (
full_playlist != undefined &&
!already_offline &&
full_playlist.length > 0
) {
for (var x = 0; x < full_playlist.length; x++) {
full_playlist[x].votes = 0;
}
List.sortList();
List.populate_list(full_playlist);
}
}
}
function before_toast(){
/*if($('.toast').length > 0) {
function before_toast() {
/*if($('.toast').length > 0) {
var toastElement = $('.toast').first()[0];
var toastInstance = toastElement.M_Toast;
toastInstance.remove();
}*/
M.Toast.dismissAll();
//Materialize.Toast.removeAll();
M.Toast.dismissAll();
//Materialize.Toast.removeAll();
}
document.addEventListener("click", function(e) {
document.addEventListener(
"click",
function(e) {
handleEvent(e, e.target, false, "click");
}, false);
},
false
);
addListener("click", "#zoffbutton", function(e) {
Player.pauseVideo();
window.open("https://zoff.me/" + chan.toLowerCase() + "/", '_blank');
addListener("click", ".channel-info-container", function(e) {
this.preventDefault();
Player.pauseVideo();
window.open("https://zoff.me/" + chan.toLowerCase() + "/", "_blank");
});
addListener("click", ".vote-container", function(e) {
var that = e;
var id = that.getAttribute("data-video-id");
List.vote(id, "pos");
var that = e;
var id = that.getAttribute("data-video-id");
List.vote(id, "pos");
});
addListener("click", ".prev_page", function(e) {
event.preventDefault();
List.dynamicContentPage(-1);
event.preventDefault();
List.dynamicContentPage(-1);
});
addListener("click", "#player_overlay", function(event) {
if(videoSource == "soundcloud") Playercontrols.play_pause();
if (videoSource == "soundcloud") Playercontrols.play_pause();
});
addListener("click", ".next_page", function(e) {
event.preventDefault();
List.dynamicContentPage(1);
event.preventDefault();
List.dynamicContentPage(1);
});
addListener("click", ".prev", function(event){
this.preventDefault();
if(!offline) return;
List.skip(false);
addListener("click", ".prev", function(event) {
this.preventDefault();
if (!offline) return;
List.skip(false);
});
addListener("click", ".skip", function(event){
this.preventDefault();
if(!offline) return;
List.skip(true);
addListener("click", ".skip", function(event) {
this.preventDefault();
//if(!offline) return;
List.skip(true);
});
addListener("click", ".last_page", function(e){
event.preventDefault();
List.dynamicContentPage(10);
addListener("click", ".last_page", function(e) {
event.preventDefault();
List.dynamicContentPage(10);
});
addListener("click", ".first_page", function(e){
event.preventDefault();
List.dynamicContentPage(-10);
addListener("click", ".first_page", function(e) {
event.preventDefault();
List.dynamicContentPage(-10);
});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,82 +1,114 @@
var Hostcontroller = {
enabled: true,
enabled: true,
old_id: null,
old_id: null,
host_listener: function(id) {
if(client) return;
Helper.log([
"Host-listener triggered",
"Host-listener id:" + id
]);
if(Hostcontroller.old_id === null) Hostcontroller.old_id = id;
else {
socket.removeAllListeners(id);
began = false;
Hostcontroller.old_id = id;
}
var codeURL = window.location.protocol + "//remote."+window.location.hostname+"/"+id;
if(embed) {
if(window.parentWindow && window.parentOrigin) {
window.parentWindow.postMessage({type: "controller", id: id}, window.parentOrigin);
}
} else if(!embed) {
if(window.location.pathname == "/") return;
document.querySelector("#code-text").innerText = id;
document.querySelector("#code-qr").setAttribute("src", "https://chart.googleapis.com/chart?chs=221x221&cht=qr&choe=UTF-8&chld=L|1&chl="+codeURL);
document.querySelector("#code-link").setAttribute("href", codeURL);
}
if(!began) {
began = true;
setup_host_listener(id);
}
},
host_on_action: function(arr) {
if(client) return;
if(enabled){
if(arr.type == "volume") {
try {
Playercontrols.visualVolume(arr.value);
Player.setVolume(arr.value);
Player.soundcloud_player.setVolume(arr.value / 100);
try {
localStorage.setItem("volume", arr.value);
} catch(e){}
Playercontrols.choose_button(arr.value, false);
} catch(e) {}
} else if(arr.type == "channel") {
if(window.location.pathname == "/") return;
socket.emit("change_channel");
Admin.beginning = true;
chan = arr.value.toLowerCase();
Helper.setHtml("#chan", Helper.upperFirst(chan));
var shareCodeUrl = window.location.protocol + "//client."+window.location.hostname+"/r/"+btoa(encodeURIComponent(chan.toLowerCase()));
document.getElementById("share-join-qr").setAttribute("src", "https://chart.googleapis.com/chart?chs=221x221&cht=qr&choe=UTF-8&chld=L|1&chl="+shareCodeUrl);
Helper.setHtml("#channel-name-join", "client." + window.location.hostname + "/" + encodeURIComponent(chan.toLowerCase()));
w_p = true;
var add = "";
//if(private_channel) add = Crypt.getCookie("_uI") + "_";
socket.emit("list", {version: parseInt(_VERSION), channel: add + chan.toLowerCase()});
window.history.pushState("object or string", "Title", "/"+chan.toLowerCase());
} else if(arr.type == "pause") {
Player.pauseVideo();
} else if(arr.type == "play") {
Player.playVideo();
} else if(arr.type == "skip") {
List.skip();
}
}
},
change_enabled:function(val){
if(client) return;
enabled = val;
try {
document.querySelector(".remote_switch_class").checked = enabled;
}catch(e) {}
host_listener: function(id) {
if (client) return;
Helper.log(["Host-listener triggered", "Host-listener id:" + id]);
if (Hostcontroller.old_id === null) Hostcontroller.old_id = id;
else {
socket.removeAllListeners(id);
began = false;
Hostcontroller.old_id = id;
}
var codeURL =
window.location.protocol + "//remote." + window.location.host + "/" + id;
if (embed) {
if (window.parentWindow && window.parentOrigin) {
window.parentWindow.postMessage(
{ type: "controller", id: id },
window.parentOrigin
);
}
} else if (!embed) {
if (window.location.pathname == "/") return;
document.querySelector("#code-text").innerText = id;
document
.querySelector("#code-qr")
.setAttribute(
"src",
"https://chart.googleapis.com/chart?chs=221x221&cht=qr&choe=UTF-8&chld=L|1&chl=" +
codeURL
);
document.querySelector("#code-link").setAttribute("href", codeURL);
}
if (!began) {
began = true;
setup_host_listener(id);
}
},
host_on_action: function(arr) {
if (client) return;
if (Hostcontroller.enabled) {
if (arr.type == "volume") {
try {
Playercontrols.visualVolume(arr.value);
Player.setVolume(arr.value);
if (scUsingWidget) Player.soundcloud_player.setVolume(arr.value);
else Player.soundcloud_player.setVolume(arr.value / 100);
try {
localStorage.setItem("volume", arr.value);
} catch (e) {}
Playercontrols.choose_button(arr.value, false);
} catch (e) {}
} else if (arr.type == "channel") {
if (window.location.pathname == "/") return;
socket.emit("change_channel");
Admin.beginning = true;
chan = arr.value.toLowerCase();
Helper.setHtml("#chan", Helper.upperFirst(chan));
var shareCodeUrl =
window.location.protocol +
"//client." +
window.location.hostname +
"/r/" +
btoa(encodeURIComponent(chan.toLowerCase()));
document
.getElementById("share-join-qr")
.setAttribute(
"src",
"https://chart.googleapis.com/chart?chs=221x221&cht=qr&choe=UTF-8&chld=L|1&chl=" +
shareCodeUrl
);
Helper.setHtml(
"#channel-name-join",
"client." +
window.location.hostname +
"/" +
encodeURIComponent(chan.toLowerCase())
);
w_p = true;
var add = "";
//if(private_channel) add = Crypt.getCookie("_uI") + "_";
socket.emit("list", {
version: parseInt(_VERSION),
channel: add + chan.toLowerCase()
});
window.history.pushState(
"object or string",
"Title",
"/" + chan.toLowerCase()
);
} else if (arr.type == "pause") {
Player.pauseVideo();
} else if (arr.type == "play") {
Player.playVideo();
} else if (arr.type == "skip") {
List.skip();
}
}
},
change_enabled: function(val) {
if (client) return;
Hostcontroller.enabled = val;
try {
document.querySelector(".remote_switch_class").checked =
Hostcontroller.enabled;
} catch (e) {}
}
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,60 +1,89 @@
var Mobile_remote = {
id: "",
id: "",
get_input: function(value) {
if(Mobile_remote.id === "") {
Mobile_remote.set_id(value.toLowerCase());
} else {
Mobile_remote.set_channel(value.toLowerCase());
}
},
get_input: function(value) {
if (Mobile_remote.id === "") {
Mobile_remote.set_id(value.toLowerCase());
} else {
Mobile_remote.set_channel(value.toLowerCase());
}
},
set_id: function(id) {
Mobile_remote.id = id;
document.getElementById("pausebutton_remote").removeAttribute("disabled");
document.getElementById("skipbutton_remote").removeAttribute("disabled", false);
document.getElementById("playbutton_remote").removeAttribute("disabled", false);
document.getElementById("skipbutton_remote").removeAttribute("disabled", false);
document.getElementById("remote_channel").value = "";
document.getElementById("remote_channel").setAttribute("placeholder", "Change channel");
document.getElementById("remote_header").innerText = "Controlling " + id;
Helper.css("#volume-control-remote", "display", "inline-block");
document.querySelector(".slider-vol-mobile").setAttribute("style", "display: inline-block !important");
},
set_id: function(id) {
Mobile_remote.id = id;
document.getElementById("pausebutton_remote").removeAttribute("disabled");
document
.getElementById("skipbutton_remote")
.removeAttribute("disabled", false);
document
.getElementById("playbutton_remote")
.removeAttribute("disabled", false);
document
.getElementById("skipbutton_remote")
.removeAttribute("disabled", false);
document.getElementById("remote_channel").value = "";
document
.getElementById("remote_channel")
.setAttribute("placeholder", "Change channel");
document.getElementById("remote_header").innerText = "Controlling " + id;
Helper.css("#volume-control-remote", "display", "inline-block");
document
.querySelector(".slider-vol-mobile")
.setAttribute("style", "display: inline-block !important");
},
set_channel: function(channel_name) {
socket.emit("id", {id: Mobile_remote.id, type: "channel", value: channel_name});
},
set_channel: function(channel_name) {
socket.emit("id", {
id: Mobile_remote.id,
type: "channel",
value: channel_name
});
},
play_remote: function() {
socket.emit("id", {id: Mobile_remote.id, type: "play", value: "mock"});
},
play_remote: function() {
socket.emit("id", { id: Mobile_remote.id, type: "play", value: "mock" });
},
pause_remote: function() {
socket.emit("id", {id: Mobile_remote.id, type: "pause", value: "mock"});
},
pause_remote: function() {
socket.emit("id", { id: Mobile_remote.id, type: "pause", value: "mock" });
},
skip_remote: function() {
socket.emit("id", {id: Mobile_remote.id, type: "skip", value: "mock"});
},
skip_remote: function() {
socket.emit("id", { id: Mobile_remote.id, type: "skip", value: "mock" });
},
initiate_volume: function() {
var vol = 100;
document.getElementById("volume-control-remote").insertAdjacentHTML("beforeend", "<div class='volume-slid-remote'></div>");
document.getElementById("volume-control-remote").insertAdjacentHTML("beforeend", "<div class='volume-handle-remote'></div>");
Helper.css(".volume-slid-remote", "width", vol + "%");
Helper.css(".volume-handle-remote", "left", "calc(" + vol + "% - 1px)");
document.getElementById("volume-control-remote").addEventListener("touchstart", function(e) {
e.preventDefault();
Playercontrols.dragMouseDown(e);
}, false);
document.getElementById("volume-control-remote").addEventListener("touchmove", function(e) {
e.preventDefault();
Playercontrols.elementDrag(e);
}, false);
}
initiate_volume: function() {
var vol = 100;
document
.getElementById("volume-control-remote")
.insertAdjacentHTML(
"beforeend",
"<div class='volume-slid-remote'></div>"
);
document
.getElementById("volume-control-remote")
.insertAdjacentHTML(
"beforeend",
"<div class='volume-handle-remote'></div>"
);
Helper.css(".volume-slid-remote", "width", vol + "%");
Helper.css(".volume-handle-remote", "left", "calc(" + vol + "% - 1px)");
document.getElementById("volume-control-remote").addEventListener(
"touchstart",
function(e) {
e.preventDefault();
Playercontrols.dragMouseDown(e);
},
false
);
document.getElementById("volume-control-remote").addEventListener(
"touchmove",
function(e) {
e.preventDefault();
Playercontrols.elementDrag(e);
},
false
);
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,432 +1,521 @@
var Playercontrols = {
stopInterval: false,
stopInterval: false,
initYoutubeControls: function() {
Playercontrols.initControls();
},
initControls: function() {
document
.getElementById("volume-button")
.addEventListener("click", Playercontrols.mute_video);
document
.getElementById("playpause")
.addEventListener("click", Playercontrols.play_pause);
document
.getElementById("volume-button-overlay")
.addEventListener("click", Playercontrols.mute_video);
document
.getElementById("playpause-overlay")
.addEventListener("click", Playercontrols.play_pause);
document
.getElementById("fullscreen")
.addEventListener("click", Playercontrols.fullscreen);
},
initYoutubeControls: function() {
Playercontrols.initControls();
},
initControls: function() {
document.getElementById("volume-button").addEventListener("click", Playercontrols.mute_video);
document.getElementById("playpause").addEventListener("click", Playercontrols.play_pause);
document.getElementById("volume-button-overlay").addEventListener("click", Playercontrols.mute_video);
document.getElementById("playpause-overlay").addEventListener("click", Playercontrols.play_pause);
document.getElementById("fullscreen").addEventListener("click", Playercontrols.fullscreen);
},
initSlider: function() {
try {
vol = (Crypt.get_volume());
} catch(e){
vol = 100;
}
try {
if(document.getElementsByClassName("volume-slid")) {
document.getElementById("volume").innerHTML = "";
}
}catch(e){}
if(Helper.mobilecheck() || slider_type == "vertical") {
//slider_values.orientation = "vertical";
if(!document.querySelector(".volume-container").classList.contains("hide")) {
Helper.toggleClass(".volume-container", "hide");
}
}
document.getElementById("volume").insertAdjacentHTML("beforeend", "<div class='volume-slid " + slider_type + "'></div>");
document.getElementById("volume").insertAdjacentHTML("beforeend", "<div class='volume-handle " + slider_type + "'></div>");
if(slider_type != "vertical") {
Helper.removeClass("#volume", "vertical");
Helper.css(".volume-slid", "width", vol + "%");
Helper.css(".volume-handle", "left", "calc(" + vol + "% - 1px)");
} else {
Helper.addClass("#volume", "vertical");
Helper.css(".volume-slid", "height", vol + "%");
Helper.css(".volume-handle", "bottom", "calc(" + vol + "% - 1px)");
}
Playercontrols.choose_button(vol, false);
//document.getElementsByClassName("volume-handle")[0].onmousedown = Playercontrols.dragMouseDown;
//Playercontrols.visualVolume(slider_values);
//document.getElementsByClassName("volume-slid")[0].onmousedown = Playercontrols.dragMouseDown;
document.getElementById("volume").onmousedown = function(e) {
Playercontrols.dragMouseDown(e, "player");
}
if(!Helper.mobilecheck()) {
document.getElementById("volume").onclick = function(e) {
Playercontrols.elementDrag(e, "player");
Playercontrols.closeDragElement("player");
}
}
document.getElementById("volume").addEventListener("touchstart", function(e) {
e.preventDefault();
Playercontrols.dragMouseDown(e, "player");
}, false);
},
dragMouseDown: function(e, element) {
e = e || window.event;
// get the mouse cursor position at startup:
document.onmouseup = function() {
Playercontrols.closeDragElement(element);
}
document.getElementById("volume").addEventListener("touchend", function() {
Playercontrols.closeDragElement(element);
}, false);
// call a function whenever the cursor moves:
document.onmousemove = function(e) {
Playercontrols.elementDrag(e, element);
}
document.getElementById("volume").addEventListener("touchmove", function(e) {
e.preventDefault();
Playercontrols.elementDrag(e, element);
}, false);
},
elementDrag: function(e, element) {
var elmnt;
var cmp_elmnt;
var slid_elmnt;
if(element == "player") {
elmnt = document.getElementsByClassName("volume-handle")[0];
cmp_elmnt = document.getElementById("volume");
slid_elmnt = document.getElementsByClassName("volume-slid")[0];
} else {
elmnt = document.getElementsByClassName("volume-handle-remote")[0];
cmp_elmnt = document.getElementById("volume-control-remote");
slid_elmnt = document.getElementsByClassName("volume-slid-remote")[0];
}
e = e || window.event;
var pos3 = e.clientX;
var pos4 = e.clientY;
if(pos3 == undefined) {
pos3 = e.touches[0].clientX;
}
if(pos4 == undefined) {
pos4 = e.touches[0].clientY;
}
var volume = 0;
if(slider_type != "vertical" || element != "player") {
if(elmnt.className.indexOf("ui-state-active") == -1) {
elmnt.className += " ui-state-active";
}
var pos = pos3 - cmp_elmnt.offsetLeft;
if(pos > -1 && pos < cmp_elmnt.offsetWidth + 1) {
elmnt.style.left = pos + "px";
volume = pos / cmp_elmnt.offsetWidth;
} else if(pos < 1) {
elmnt.style.left = 0 + "px";
volume = 0;
} else {
elmnt.style.left = cmp_elmnt.offsetWidth + "px";
volume = 1;
}
slid_elmnt.style.width = volume * 100 + "%";
if(element == "player") Playercontrols.setVolume(volume * 100);
else socket.emit("id", {id: Mobile_remote.id, type: "volume", value: volume * 100});
} else {
var pos = pos4 - cmp_elmnt.offsetTop;
var pos0 = window.innerHeight - pos - 14;
if(pos0 > 64 && pos0 < 164) {
volume = (pos0 - 64) / 100;
} else if(pos0 < 65) {
volume = 0;
} else {
volume = 1;
}
slid_elmnt.style.height = volume * 100 + "%";
Playercontrols.setVolume(volume * 100);
}
try{Crypt.set_volume(volume * 100);}catch(e){
}
},
closeDragElement: function(element) {
/* stop moving when mouse button is released:*/
var elmnt;
if(element == "player") {
elmnt = document.getElementsByClassName("volume-handle")[0];
} else {
elmnt = document.getElementsByClassName("volume-handle-remote")[0];
}
if(elmnt.className.indexOf("ui-state-active") > -1) {
setTimeout(function(){
elmnt.classList.remove("ui-state-active");
}, 1);
}
document.onmouseup = null;
document.onmousemove = null;
if(element == "player") {
document.getElementById("volume").removeEventListener("touchmove", function(e) {
e.preventDefault();
Playercontrols.elementDrag(e, element);
}, false);
document.getElementById("volume").removeEventListener("touchend", function() {
Playercontrols.closeDragElement(element);
}, false);
} else {
document.getElementById("volume-control-remote").removeEventListener("touchmove", function(e) {
e.preventDefault();
Playercontrols.elementDrag(e);
}, false);
document.getElementById("volume-control-remote").removeEventListener("touchend", function() {
Playercontrols.closeDragElement();
}, false);
}
},
fullscreen: function() {
var playerElement = document.getElementById("player");
var requestFullScreen = playerElement.requestFullScreen || playerElement.mozRequestFullScreen || playerElement.webkitRequestFullScreen;
if (requestFullScreen) {
requestFullScreen.bind(playerElement)();
}
},
play_pause: function() {
if(!chromecastAvailable){
if(videoSource == "soundcloud") {
if(!Player.soundcloud_player.isPlaying()) {
Player.playVideo();
} else {
Player.pauseVideo();
}
} else {
if(Player.player.getPlayerState() == YT.PlayerState.PLAYING)
{
Player.pauseVideo();
if(Helper.mobilecheck() && !window.MSStream){
//if(Helper.mobilecheck() && !/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream){
//document.getElementById("player").style.display = "none";
Helper.css("#player", "display", "none");
Helper.toggleClass(".video-container", "click-through");
Helper.toggleClass(".page-footer", "padding-bottom-extra");
}
} else if(Player.player.getPlayerState() == YT.PlayerState.PAUSED || Player.player.getPlayerState() === YT.PlayerState.ENDED || (Player.player.getPlayerState() === YT.PlayerState.CUED)){
Player.playVideo();
//if(Helper.mobilecheck() && !/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream){
if(Helper.mobilecheck() && !window.MSStream){
//document.getElementById("player").style.display = "block";
Helper.css("#player", "display", "block");
Helper.toggleClass(".video-container", "click-through");
Helper.toggleClass(".page-footer", "padding-bottom-extra");
}
}
}
} else {
Playercontrols.play_pause_show();
}
},
play_pause_show: function() {
if(chromecastAvailable){
if(document.getElementById("play").classList.contains("hide")){
Player.pauseVideo();
} else if(document.getElementById("pause").classList.contains("hide")){
Player.playVideo();
}
} else {
if(!document.getElementById("pause").classList.contains("hide")) {
Helper.toggleClass("#pause", "hide");
Helper.toggleClass("#pause-overlay", "hide");
}
if(document.getElementById("play").classList.contains("hide")) {
Helper.toggleClass("#play", "hide");
Helper.toggleClass("#play-overlay", "hide");
}
}
},
settings: function() {
Helper.toggleClass("#qS", "hide");
},
changeQuality: function(wantedQ) {
if(Player.player.getPlaybackQuality != wantedQ) {
Player.player.setPlaybackQuality(wantedQ);
Player.player.getPlaybackQuality();
}
Helper.toggleClass("#qS", "hide");
},
mute_video: function() {
if(Helper.mobilecheck() || slider_type == "vertical") {
Helper.toggleClass(".volume-container", "hide");
} else {
if(!Player.player.isMuted()) {
if(chromecastAvailable) castSession.sendMessage("urn:x-cast:zoff.me", {type: "mute"});
Playercontrols.choose_button(0, true);
Player.player.mute();
} else {
if(chromecastAvailable)castSession.sendMessage("urn:x-cast:zoff.me", {type: "unMute"});
Player.player.unMute();
Playercontrols.choose_button(Player.player.getVolume(), false);
}
}
},
setVolume: function(vol) {
Player.setVolume(vol);
Player.soundcloud_player.setVolume(vol / 100);
Playercontrols.choose_button(vol, false);
if(Player.player.isMuted())
Player.player.unMute();
},
choose_button: function(vol, mute) {
if(!mute){
if(vol >= 0 && vol <= 33) {
if(!document.getElementById("v-full").classList.contains("hide")) {
Helper.toggleClass("#v-full", "hide");
Helper.toggleClass("#v-full-overlay", "hide");
}
if(!document.getElementById("v-medium").classList.contains("hide")) {
Helper.toggleClass("#v-medium", "hide");
Helper.toggleClass("#v-medium-overlay", "hide");
}
if(document.getElementById("v-low").classList.contains("hide")) {
Helper.toggleClass("#v-low", "hide");
Helper.toggleClass("#v-low-overlay", "hide");
}
if(!document.getElementById("v-mute").classList.contains("hide")) {
Helper.toggleClass("#v-mute", "hide");
Helper.toggleClass("#v-mute-overlay", "hide");
}
} else if(vol >= 34 && vol <= 66) {
if(!document.getElementById("v-full").classList.contains("hide")) {
Helper.toggleClass("#v-full", "hide");
Helper.toggleClass("#v-full-overlay", "hide");
}
if(document.getElementById("v-medium").classList.contains("hide")) {
Helper.toggleClass("#v-medium", "hide");
Helper.toggleClass("#v-medium-overlay", "hide");
}
if(!document.getElementById("v-low").classList.contains("hide")) {
Helper.toggleClass("#v-low", "hide");
Helper.toggleClass("#v-low-overlay", "hide");
}
if(!document.getElementById("v-mute").classList.contains("hide")) {
Helper.toggleClass("#v-mute", "hide");
Helper.toggleClass("#v-mute-overlay", "hide");
}
} else if(vol >= 67 && vol <= 100) {
if(document.getElementById("v-full").classList.contains("hide")) {
Helper.toggleClass("#v-full", "hide");
Helper.toggleClass("#v-full-overlay", "hide");
}
if(!document.getElementById("v-medium").classList.contains("hide")) {
Helper.toggleClass("#v-medium", "hide");
Helper.toggleClass("#v-medium-overlay", "hide");
}
if(!document.getElementById("v-low").classList.contains("hide")) {
Helper.toggleClass("#v-low", "hide");
Helper.toggleClass("#v-low-overlay", "hide");
}
if(!document.getElementById("v-mute").classList.contains("hide")) {
Helper.toggleClass("#v-mute", "hide");
Helper.toggleClass("#v-mute-overlay", "hide");
}
}
} else {
if(!document.getElementById("v-full").classList.contains("hide")) {
Helper.toggleClass("#v-full", "hide");
Helper.toggleClass("#v-full-overlay", "hide");
}
if(!document.getElementById("v-medium").classList.contains("hide")) {
Helper.toggleClass("#v-medium", "hide");
Helper.toggleClass("#v-medium-overlay", "hide");
}
if(!document.getElementById("v-low").classList.contains("hide")) {
Helper.toggleClass("#v-low", "hide");
Helper.toggleClass("#v-low-overlay", "hide");
}
if(document.getElementById("v-mute").classList.contains("hide")) {
Helper.toggleClass("#v-mute", "hide");
Helper.toggleClass("#v-mute-overlay", "hide");
}
}
},
playPause: function() {
if(videoSource == "soundcloud") {
if(!Player.soundcloud_player.isPlaying()) {
Helper.addClass("#play", "hide");
Helper.removeClass("#pause", "hide");
Player.soundcloud_player.play();
} else {
Helper.removeClass("#play", "hide");
Helper.addClass("#pause", "hide");
Player.soundcloud_player.pause();
}
} else {
state = Player.player.getPlayerState();
button = document.getElementById("playpause");
if(state == YT.PlayerState.PLAYING) {
Player.pauseVideo();
} else if(state == YT.PlayerState.PAUSED) {
Player.playVideo();
}
}
},
visualVolume: function(val) {
var elmnt = document.getElementsByClassName("volume-handle")[0];
var cmp_elmnt = document.getElementById("volume");
var slid_elmnt = document.getElementsByClassName("volume-slid")[0];
if(slider_type != "vertical") {
var pos = (cmp_elmnt.offsetWidth / 100) * val;
var volume = 0;
//var pos = pos3 - cmp_elmnt.offsetLeft;
if(pos > -1 && pos < cmp_elmnt.offsetWidth + 1) {
elmnt.style.left = pos + "px";
volume = pos / cmp_elmnt.offsetWidth;
} else if(pos < 1) {
elmnt.style.left = 0 + "px";
volume = 0;
} else {
elmnt.style.left = cmp_elmnt.offsetWidth + "px";
volume = 1;
}
slid_elmnt.style.width = volume * 100 + "%";
Playercontrols.setVolume(volume * 100);
} else {
var pos = val;
var pos0 = window.innerHeight - pos - 14;
var volume = 0;
if(pos0 > 64 && pos0 < 164) {
volume = (pos0 - 64) / 100;
} else if(pos0 < 65) {
volume = 0;
} else {
volume = 1;
}
slid_elmnt.style.height = volume * 100 + "%";
Playercontrols.setVolume(volume * 100);
}
},
volumeOptions: function() {
if(!chromecastAvailable) {
if(Player.player.isMuted()) {
Player.player.unMute();
vol = Player.player.getVolume();
Playercontrols.visualVolume(Player.player.getVolume());
} else {
Player.player.mute();
Playercontrols.visualVolume(0);
}
}
},
hoverMute: function(foo) {
vol = Player.player.getVolume();
initSlider: function() {
try {
vol = Crypt.get_volume();
} catch (e) {
vol = 100;
}
try {
if (document.getElementsByClassName("volume-slid")) {
document.getElementById("volume").innerHTML = "";
}
} catch (e) {}
if ((Helper.mobilecheck() || slider_type == "vertical") && !embed) {
//slider_values.orientation = "vertical";
if (
!document.querySelector(".volume-container").classList.contains("hide")
) {
Helper.toggleClass(".volume-container", "hide");
}
}
document
.getElementById("volume")
.insertAdjacentHTML(
"beforeend",
"<div class='volume-slid " + slider_type + "'></div>"
);
document
.getElementById("volume")
.insertAdjacentHTML(
"beforeend",
"<div class='volume-handle " + slider_type + "'></div>"
);
if (slider_type != "vertical") {
Helper.removeClass("#volume", "vertical");
Helper.css(".volume-slid", "width", vol + "%");
Helper.css(".volume-handle", "left", "calc(" + vol + "% - 1px)");
} else {
Helper.addClass("#volume", "vertical");
Helper.css(".volume-slid", "height", vol + "%");
Helper.css(".volume-handle", "bottom", "calc(" + vol + "% - 1px)");
}
Playercontrols.choose_button(vol, false);
//document.getElementsByClassName("volume-handle")[0].onmousedown = Playercontrols.dragMouseDown;
//Playercontrols.visualVolume(slider_values);
//document.getElementsByClassName("volume-slid")[0].onmousedown = Playercontrols.dragMouseDown;
document.getElementById("volume").onmousedown = function(e) {
Playercontrols.dragMouseDown(e, "player");
};
if (!Helper.mobilecheck()) {
document.getElementById("volume").onclick = function(e) {
Playercontrols.elementDrag(e, "player");
Playercontrols.closeDragElement("player");
};
}
document.getElementById("volume").addEventListener(
"touchstart",
function(e) {
e.preventDefault();
Playercontrols.dragMouseDown(e, "player");
},
false
);
},
dragMouseDown: function(e, element) {
e = e || window.event;
// get the mouse cursor position at startup:
document.onmouseup = function() {
Playercontrols.closeDragElement(element);
};
document.getElementById("volume").addEventListener(
"touchend",
function() {
Playercontrols.closeDragElement(element);
},
false
);
// call a function whenever the cursor moves:
document.onmousemove = function(e) {
Playercontrols.elementDrag(e, element);
};
document.getElementById("volume").addEventListener(
"touchmove",
function(e) {
e.preventDefault();
Playercontrols.elementDrag(e, element);
},
false
);
},
elementDrag: function(e, element) {
var elmnt;
var cmp_elmnt;
var slid_elmnt;
if (element == "player") {
elmnt = document.getElementsByClassName("volume-handle")[0];
cmp_elmnt = document.getElementById("volume");
slid_elmnt = document.getElementsByClassName("volume-slid")[0];
} else {
elmnt = document.getElementsByClassName("volume-handle-remote")[0];
cmp_elmnt = document.getElementById("volume-control-remote");
slid_elmnt = document.getElementsByClassName("volume-slid-remote")[0];
}
e = e || window.event;
var pos3 = e.clientX;
var pos4 = e.clientY;
if (pos3 == undefined) {
pos3 = e.touches[0].clientX;
}
if (pos4 == undefined) {
pos4 = e.touches[0].clientY;
}
var volume = 0;
if (slider_type != "vertical" || element != "player") {
if (elmnt.className.indexOf("ui-state-active") == -1) {
elmnt.className += " ui-state-active";
}
var pos = pos3 - cmp_elmnt.offsetLeft;
if (pos > -1 && pos < cmp_elmnt.offsetWidth + 1) {
elmnt.style.left = pos + "px";
volume = pos / cmp_elmnt.offsetWidth;
} else if (pos < 1) {
elmnt.style.left = 0 + "px";
volume = 0;
} else {
elmnt.style.left = cmp_elmnt.offsetWidth + "px";
volume = 1;
}
slid_elmnt.style.width = volume * 100 + "%";
if (element == "player") Playercontrols.setVolume(volume * 100);
else
socket.emit("id", {
id: Mobile_remote.id,
type: "volume",
value: volume * 100
});
} else {
var pos = pos4 - cmp_elmnt.offsetTop;
var pos0 = window.innerHeight - pos - 14;
if (pos0 > 64 && pos0 < 164) {
volume = (pos0 - 64) / 100;
} else if (pos0 < 65) {
volume = 0;
} else {
volume = 1;
}
slid_elmnt.style.height = volume * 100 + "%";
Playercontrols.setVolume(volume * 100);
}
try {
Crypt.set_volume(volume * 100);
} catch (e) {}
},
closeDragElement: function(element) {
/* stop moving when mouse button is released:*/
var elmnt;
if (element == "player") {
elmnt = document.getElementsByClassName("volume-handle")[0];
} else {
elmnt = document.getElementsByClassName("volume-handle-remote")[0];
}
if (elmnt.className.indexOf("ui-state-active") > -1) {
setTimeout(function() {
elmnt.classList.remove("ui-state-active");
}, 1);
}
document.onmouseup = null;
document.onmousemove = null;
if (element == "player") {
document.getElementById("volume").removeEventListener(
"touchmove",
function(e) {
e.preventDefault();
Playercontrols.elementDrag(e, element);
},
false
);
document.getElementById("volume").removeEventListener(
"touchend",
function() {
Playercontrols.closeDragElement(element);
},
false
);
} else {
document.getElementById("volume-control-remote").removeEventListener(
"touchmove",
function(e) {
e.preventDefault();
Playercontrols.elementDrag(e);
},
false
);
document.getElementById("volume-control-remote").removeEventListener(
"touchend",
function() {
Playercontrols.closeDragElement();
},
false
);
}
},
fullscreen: function() {
var playerElement;
if (fireplace_initiated) {
playerElement = document.getElementById("fireplace_player");
} else {
playerElement = document.getElementById("player");
}
var requestFullScreen =
playerElement.requestFullScreen ||
playerElement.mozRequestFullScreen ||
playerElement.webkitRequestFullScreen;
if (requestFullScreen) {
requestFullScreen.bind(playerElement)();
}
},
play_pause: function() {
if (!chromecastAvailable) {
if (videoSource == "soundcloud") {
if (scUsingWidget) {
Player.soundcloud_player.isPaused(function(playing) {
playing = !playing;
if (!playing) {
Player.playVideo();
} else {
Player.pauseVideo();
}
was_stopped = true;
});
} else {
if (!Player.soundcloud_player.isPlaying()) {
Player.playVideo();
} else {
Player.pauseVideo();
}
}
} else {
if (Player.player.getPlayerState() == YT.PlayerState.PLAYING) {
Player.pauseVideo();
if (Helper.mobilecheck() && !window.MSStream && !embed) {
//if(Helper.mobilecheck() && !/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream){
//document.getElementById("player").style.display = "none";
Helper.css("#player", "display", "none");
Helper.toggleClass(".video-container", "click-through");
Helper.toggleClass(".page-footer", "padding-bottom-extra");
}
} else if (
Player.player.getPlayerState() == YT.PlayerState.PAUSED ||
Player.player.getPlayerState() === YT.PlayerState.ENDED ||
Player.player.getPlayerState() === YT.PlayerState.CUED
) {
Player.playVideo();
//if(Helper.mobilecheck() && !/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream){
if (Helper.mobilecheck() && !window.MSStream) {
//document.getElementById("player").style.display = "block";
Helper.css("#player", "display", "block");
Helper.toggleClass(".video-container", "click-through");
Helper.toggleClass(".page-footer", "padding-bottom-extra");
}
}
}
} else {
Playercontrols.play_pause_show();
}
},
play_pause_show: function() {
if (chromecastAvailable) {
if (document.getElementById("play").classList.contains("hide")) {
Player.pauseVideo();
} else if (document.getElementById("pause").classList.contains("hide")) {
Player.playVideo();
}
} else {
if (!document.getElementById("pause").classList.contains("hide")) {
Helper.toggleClass("#pause", "hide");
Helper.toggleClass("#pause-overlay", "hide");
}
if (document.getElementById("play").classList.contains("hide")) {
Helper.toggleClass("#play", "hide");
Helper.toggleClass("#play-overlay", "hide");
}
}
},
settings: function() {
Helper.toggleClass("#qS", "hide");
},
changeQuality: function(wantedQ) {
if (Player.player.getPlaybackQuality != wantedQ) {
Player.player.setPlaybackQuality(wantedQ);
Player.player.getPlaybackQuality();
}
Helper.toggleClass("#qS", "hide");
},
mute_video: function() {
if (Helper.mobilecheck() || slider_type == "vertical") {
Helper.toggleClass(".volume-container", "hide");
} else {
if (!Player.player.isMuted()) {
if (chromecastAvailable)
castSession.sendMessage("urn:x-cast:zoff.me", { type: "mute" });
Playercontrols.choose_button(0, true);
Player.player.mute();
} else {
if (chromecastAvailable)
castSession.sendMessage("urn:x-cast:zoff.me", { type: "unMute" });
Player.player.unMute();
Playercontrols.choose_button(Player.player.getVolume(), false);
}
}
},
setVolume: function(vol) {
Player.setVolume(vol);
if (scUsingWidget) Player.soundcloud_player.setVolume(vol);
else Player.soundcloud_player.setVolume(vol / 100);
Playercontrols.choose_button(vol, false);
if (Player.player.isMuted()) Player.player.unMute();
},
choose_button: function(vol, mute) {
if (!mute) {
if (vol >= 0 && vol <= 33) {
if (!document.getElementById("v-full").classList.contains("hide")) {
Helper.toggleClass("#v-full", "hide");
Helper.toggleClass("#v-full-overlay", "hide");
}
if (!document.getElementById("v-medium").classList.contains("hide")) {
Helper.toggleClass("#v-medium", "hide");
Helper.toggleClass("#v-medium-overlay", "hide");
}
if (document.getElementById("v-low").classList.contains("hide")) {
Helper.toggleClass("#v-low", "hide");
Helper.toggleClass("#v-low-overlay", "hide");
}
if (!document.getElementById("v-mute").classList.contains("hide")) {
Helper.toggleClass("#v-mute", "hide");
Helper.toggleClass("#v-mute-overlay", "hide");
}
} else if (vol >= 34 && vol <= 66) {
if (!document.getElementById("v-full").classList.contains("hide")) {
Helper.toggleClass("#v-full", "hide");
Helper.toggleClass("#v-full-overlay", "hide");
}
if (document.getElementById("v-medium").classList.contains("hide")) {
Helper.toggleClass("#v-medium", "hide");
Helper.toggleClass("#v-medium-overlay", "hide");
}
if (!document.getElementById("v-low").classList.contains("hide")) {
Helper.toggleClass("#v-low", "hide");
Helper.toggleClass("#v-low-overlay", "hide");
}
if (!document.getElementById("v-mute").classList.contains("hide")) {
Helper.toggleClass("#v-mute", "hide");
Helper.toggleClass("#v-mute-overlay", "hide");
}
} else if (vol >= 67 && vol <= 100) {
if (document.getElementById("v-full").classList.contains("hide")) {
Helper.toggleClass("#v-full", "hide");
Helper.toggleClass("#v-full-overlay", "hide");
}
if (!document.getElementById("v-medium").classList.contains("hide")) {
Helper.toggleClass("#v-medium", "hide");
Helper.toggleClass("#v-medium-overlay", "hide");
}
if (!document.getElementById("v-low").classList.contains("hide")) {
Helper.toggleClass("#v-low", "hide");
Helper.toggleClass("#v-low-overlay", "hide");
}
if (!document.getElementById("v-mute").classList.contains("hide")) {
Helper.toggleClass("#v-mute", "hide");
Helper.toggleClass("#v-mute-overlay", "hide");
}
}
} else {
if (!document.getElementById("v-full").classList.contains("hide")) {
Helper.toggleClass("#v-full", "hide");
Helper.toggleClass("#v-full-overlay", "hide");
}
if (!document.getElementById("v-medium").classList.contains("hide")) {
Helper.toggleClass("#v-medium", "hide");
Helper.toggleClass("#v-medium-overlay", "hide");
}
if (!document.getElementById("v-low").classList.contains("hide")) {
Helper.toggleClass("#v-low", "hide");
Helper.toggleClass("#v-low-overlay", "hide");
}
if (document.getElementById("v-mute").classList.contains("hide")) {
Helper.toggleClass("#v-mute", "hide");
Helper.toggleClass("#v-mute-overlay", "hide");
}
}
},
playPause: function() {
if (videoSource == "soundcloud") {
if (scUsingWidget) {
Player.soundcloud_player.isPaused(function(playing) {
playing = !playing;
if (!playing) {
Helper.addClass("#play", "hide");
Helper.removeClass("#pause", "hide");
Player.soundcloud_player.play();
} else {
Helper.removeClass("#play", "hide");
Helper.addClass("#pause", "hide");
Player.soundcloud_player.pause();
}
});
} else {
if (!Player.soundcloud_player.isPlaying()) {
Helper.addClass("#play", "hide");
Helper.removeClass("#pause", "hide");
Player.soundcloud_player.play();
} else {
Helper.removeClass("#play", "hide");
Helper.addClass("#pause", "hide");
Player.soundcloud_player.pause();
}
}
} else {
state = Player.player.getPlayerState();
button = document.getElementById("playpause");
if (state == YT.PlayerState.PLAYING) {
Player.pauseVideo();
} else if (state == YT.PlayerState.PAUSED) {
Player.playVideo();
}
}
},
visualVolume: function(val) {
var elmnt = document.getElementsByClassName("volume-handle")[0];
var cmp_elmnt = document.getElementById("volume");
var slid_elmnt = document.getElementsByClassName("volume-slid")[0];
if (slider_type != "vertical") {
var pos = (cmp_elmnt.offsetWidth / 100) * val;
var volume = 0;
//var pos = pos3 - cmp_elmnt.offsetLeft;
if (pos > -1 && pos < cmp_elmnt.offsetWidth + 1) {
elmnt.style.left = pos + "px";
volume = pos / cmp_elmnt.offsetWidth;
} else if (pos < 1) {
elmnt.style.left = 0 + "px";
volume = 0;
} else {
elmnt.style.left = cmp_elmnt.offsetWidth + "px";
volume = 1;
}
slid_elmnt.style.width = volume * 100 + "%";
Playercontrols.setVolume(volume * 100);
} else {
var pos = val;
var pos0 = window.innerHeight - pos - 14;
var volume = 0;
if (pos0 > 64 && pos0 < 164) {
volume = (pos0 - 64) / 100;
} else if (pos0 < 65) {
volume = 0;
} else {
volume = 1;
}
slid_elmnt.style.height = volume * 100 + "%";
Playercontrols.setVolume(volume * 100);
}
},
volumeOptions: function() {
if (!chromecastAvailable) {
if (Player.player.isMuted()) {
Player.player.unMute();
vol = Player.player.getVolume();
Playercontrols.visualVolume(Player.player.getVolume());
} else {
Player.player.mute();
Playercontrols.visualVolume(0);
}
}
},
hoverMute: function(foo) {
vol = Player.player.getVolume();
}
};

View File

@@ -2,107 +2,133 @@ var start = true;
var dynamicListeners = {};
mobilecheck = function() {
var check = false;
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true;})(navigator.userAgent||navigator.vendor||window.opera);
return check;
var check = false;
(function(a) {
if (
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(
a
) ||
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
a.substr(0, 4)
)
)
check = true;
})(navigator.userAgent || navigator.vendor || window.opera);
return check;
};
window.addEventListener("DOMContentLoaded", function (){
window.addEventListener(
"DOMContentLoaded",
function() {
document.title = "Zoff Remote";
setTimeout(function(){document.getElementById("search").focus();},500);
setTimeout(function() {
document.getElementById("search").focus();
}, 500);
var connection_options = {
'sync disconnect on unload':true,
'secure': true
"sync disconnect on unload": true,
secure: true
};
M.Modal.init(document.getElementById("about"));
M.Modal.init(document.getElementById("contact"));
M.Modal.init(document.getElementById("help"));
if(window.location.hostname == "remote.zoff.me") add = "https://zoff.me";
else add = "localhost";
socket = io.connect(add+':8080', connection_options);
socket.on('update_required', function() {
window.location.reload(true);
socket = io.connect(
window.location.protocol + "//" + window.location.host,
connection_options
);
socket.on("update_required", function() {
window.location.reload(true);
});
id = window.location.pathname.split("/")[1];
if(id)
{
id = id.toLowerCase();
Remotecontroller.control();
if (id) {
id = id.toLowerCase();
Remotecontroller.control();
}
}, false);
},
false
);
function handleEvent(e, target, tried, type) {
for(var y = 0; y < e.path.length; y++) {
var target = e.path[y];
if(dynamicListeners[type] && dynamicListeners[type]["#" + target.id]) {
dynamicListeners[type]["#" + target.id].call(target);
return;
} else {
if(target.classList == undefined) return;
for(var i = 0; i < target.classList.length; i++) {
if(dynamicListeners[type] && dynamicListeners[type]["." + target.classList[i]]) {
dynamicListeners[type]["." + target.classList[i]].call(target);
return;
}
}
for (var y = 0; y < e.path.length; y++) {
var target = e.path[y];
if (dynamicListeners[type] && dynamicListeners[type]["#" + target.id]) {
dynamicListeners[type]["#" + target.id].call(target);
return;
} else {
if (target.classList == undefined) return;
for (var i = 0; i < target.classList.length; i++) {
if (
dynamicListeners[type] &&
dynamicListeners[type]["." + target.classList[i]]
) {
dynamicListeners[type]["." + target.classList[i]].call(target);
return;
}
}
}
}
}
function addListener(type, element, callback) {
if(dynamicListeners[type] == undefined) dynamicListeners[type] = {};
dynamicListeners[type][element] = callback;
if (dynamicListeners[type] == undefined) dynamicListeners[type] = {};
dynamicListeners[type][element] = callback;
}
document.addEventListener("click", function(e) {
document.addEventListener(
"click",
function(e) {
handleEvent(e, e.target, false, "click");
}, true);
document.addEventListener("submit", function(e) {
},
true
);
document.addEventListener(
"submit",
function(e) {
handleEvent(e, e.target, false, "submit");
}, true);
},
true
);
addListener("click", "#playbutton", function() {
socket.emit("id", {id: id, type: "play", value: "mock"});
socket.emit("id", { id: id, type: "play", value: "mock" });
});
addListener("click", "#pausebutton", function() {
socket.emit("id", {id: id, type: "pause", value: "mock"});
socket.emit("id", { id: id, type: "pause", value: "mock" });
});
addListener("click", "#skipbutton", function() {
socket.emit("id", {id: id, type: "skip", value: "mock"});
socket.emit("id", { id: id, type: "skip", value: "mock" });
});
addListener("submit", "#remoteform", function(e) {
event.preventDefault();
Remotecontroller.control();
event.preventDefault();
Remotecontroller.control();
});
var Remotecontroller = {
control: function() {
if (start) {
if (!id) {
id = document.getElementById("remoteform").chan.value;
window.history.pushState("object or string", "Title", "/" + id);
}
document.getElementById("remoteform").chan.value = "";
start = false;
control: function() {
if(start) {
if(!id) {
id = document.getElementById("remoteform").chan.value;
window.history.pushState("object or string", "Title", "/"+id);
}
document.getElementById("remoteform").chan.value = "";
start = false;
Helper.css(".volume-elements", "display", "flex");
Helper.css(".rc", "display", "block");
Helper.css(".volume-elements", "display", "flex");
Helper.css(".rc", "display", "block");
//document.getElementById("base").setAttribute("onsubmit", "control(); return false;");
document.getElementById("remote-text").innerText =
"Controlling " + id.toUpperCase();
document.getElementById("search").setAttribute("length", "18");
document.getElementById("search").setAttribute("maxlength", "18");
document.getElementById("forsearch").innerText =
"Type new channel name to change to";
//document.getElementById("base").setAttribute("onsubmit", "control(); return false;");
document.getElementById("remote-text").innerText = "Controlling "+ id.toUpperCase();
document.getElementById("search").setAttribute("length", "18");
document.getElementById("search").setAttribute("maxlength", "18");
document.getElementById("forsearch").innerText = "Type new channel name to change to";
//
/*$("#volume-control").slider({
//
/*$("#volume-control").slider({
min: 0,
max: 100,
value: 100,
@@ -113,94 +139,123 @@ var Remotecontroller = {
}
//});*/
document.getElementById("volume").insertAdjacentHTML("beforeend", "<div class='volume-slid'></div>");
document.getElementById("volume").insertAdjacentHTML("beforeend", "<div class='volume-handle'></div>");
document
.getElementById("volume")
.insertAdjacentHTML("beforeend", "<div class='volume-slid'></div>");
document
.getElementById("volume")
.insertAdjacentHTML("beforeend", "<div class='volume-handle'></div>");
Helper.css(".volume-slid", "width", "100%");
Helper.css(".volume-handle", "left", "calc(100% - 1px)");
//document.getElementsByClassName("volume-handle")[0].onmousedown = Remotecontroller.dragMouseDown;
//$("#volume").slider(slider_values);
//document.getElementsByClassName("volume-slid")[0].onmousedown = Remotecontroller.dragMouseDown;
document.getElementById("volume").onmousedown = Remotecontroller.dragMouseDown;
document.getElementById("volume").addEventListener("touchstart", function(e) {
e.preventDefault();
Remotecontroller.dragMouseDown(e);
}, false);
document.getElementById("volume").onclick = function(e) {
Remotecontroller.elementDrag(e);
Remotecontroller.closeDragElement();
}
} else {
socket.emit("id", {id: id, type: "channel", value: document.getElementById("search").value.toLowerCase()});
document.getElementById("search").value = "";
}
Helper.css(".volume-slid", "width", "100%");
Helper.css(".volume-handle", "left", "calc(100% - 1px)");
//document.getElementsByClassName("volume-handle")[0].onmousedown = Remotecontroller.dragMouseDown;
//$("#volume").slider(slider_values);
//document.getElementsByClassName("volume-slid")[0].onmousedown = Remotecontroller.dragMouseDown;
document.getElementById("volume").onmousedown =
Remotecontroller.dragMouseDown;
document.getElementById("volume").addEventListener(
"touchstart",
function(e) {
e.preventDefault();
Remotecontroller.dragMouseDown(e);
},
false
);
document.getElementById("volume").onclick = function(e) {
Remotecontroller.elementDrag(e);
Remotecontroller.closeDragElement();
};
} else {
socket.emit("id", {
id: id,
type: "channel",
value: document.getElementById("search").value.toLowerCase()
});
document.getElementById("search").value = "";
}
},
},
dragMouseDown: function(e) {
e = e || window.event;
// get the mouse cursor position at startup:
document.onmouseup = Remotecontroller.closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = Remotecontroller.elementDrag;
document.getElementById("volume").addEventListener(
"touchend",
function() {
Remotecontroller.closeDragElement();
},
false
);
document.getElementById("volume").addEventListener(
"touchmove",
function(e) {
e.preventDefault();
Remotecontroller.elementDrag(e);
},
false
);
},
elementDrag: function(e) {
var elmnt = document.getElementsByClassName("volume-handle")[0];
e = e || window.event;
dragMouseDown: function(e) {
e = e || window.event;
// get the mouse cursor position at startup:
document.onmouseup = Remotecontroller.closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = Remotecontroller.elementDrag;
document.getElementById("volume").addEventListener("touchend", function() {
Remotecontroller.closeDragElement();
}, false);
document.getElementById("volume").addEventListener("touchmove", function(e) {
e.preventDefault();
Remotecontroller.elementDrag(e);
}, false);
},
var pos3 = e.clientX;
if (pos3 == undefined) {
pos3 = e.touches[0].clientX;
}
elementDrag: function(e) {
var elmnt = document.getElementsByClassName("volume-handle")[0];
e = e || window.event;
if (elmnt.className.indexOf("ui-state-active") == -1) {
elmnt.className += " ui-state-active";
}
var pos = pos3 - document.getElementById("volume").offsetLeft;
if (pos > -1 && pos < document.getElementById("volume").offsetWidth + 1) {
elmnt.style.left = pos + "px";
var volume = pos / document.getElementById("volume").offsetWidth;
document.getElementsByClassName("volume-slid")[0].style.width =
volume * 100 + "%";
} else if (pos < 0) {
var volume = 0;
document.getElementsByClassName("volume-slid")[0].style.width =
volume * 100 + "%";
} else {
var volume = 1;
document.getElementsByClassName("volume-slid")[0].style.width =
volume * 100 + "%";
}
var pos3 = e.clientX;
if(pos3 == undefined) {
pos3 = e.touches[0].clientX;
}
socket.emit("id", { id: id, type: "volume", value: volume * 100 });
if(elmnt.className.indexOf("ui-state-active") == -1) {
elmnt.className += " ui-state-active";
}
var pos = pos3 - document.getElementById("volume").offsetLeft;
if(pos > -1 && pos < document.getElementById("volume").offsetWidth + 1) {
elmnt.style.left = pos + "px";
var volume = pos / document.getElementById("volume").offsetWidth;
document.getElementsByClassName("volume-slid")[0].style.width = volume * 100 + "%";
} else if(pos < 0) {
var volume = 0;
document.getElementsByClassName("volume-slid")[0].style.width = volume * 100 + "%";
} else {
var volume = 1;
document.getElementsByClassName("volume-slid")[0].style.width = volume * 100 + "%";
}
try {
Crypt.set_volume(volume * 100);
} catch (e) {}
},
socket.emit("id", {id: id, type: "volume", value: volume * 100});
closeDragElement: function() {
/* stop moving when mouse button is released:*/
var elmnt = document.getElementsByClassName("volume-handle")[0];
if (elmnt.className.indexOf("ui-state-active") > -1) {
setTimeout(function() {
elmnt.classList.remove("ui-state-active");
}, 1);
}
document.onmouseup = null;
document.onmousemove = null;
try{Crypt.set_volume(volume * 100);}catch(e){}
},
closeDragElement: function() {
/* stop moving when mouse button is released:*/
var elmnt = document.getElementsByClassName("volume-handle")[0];
if(elmnt.className.indexOf("ui-state-active") > -1) {
setTimeout(function(){
elmnt.classList.remove("ui-state-active");
}, 1);
}
document.onmouseup = null;
document.onmousemove = null;
document.getElementById("volume").removeEventListener("touchmove", function(e) {
e.preventDefault();
Playercontrols.elementDrag(e);
});
document.getElementById("volume").removeEventListener("touchend", function() {
Playercontrols.closeDragElement();
}, false);
},
document
.getElementById("volume")
.removeEventListener("touchmove", function(e) {
e.preventDefault();
Playercontrols.elementDrag(e);
});
document.getElementById("volume").removeEventListener(
"touchend",
function() {
Playercontrols.closeDragElement();
},
false
);
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,113 +1,164 @@
var Suggestions = {
catchUserSuggests: function(params, single) {
if (single) {
number_suggested = number_suggested + 1;
} else {
number_suggested = number_suggested + params.length;
}
for (var i = 0; i < params.length; i++) {
if (document.querySelectorAll("#suggested-" + params[i].id).length > 0) {
number_suggested -= 1;
}
}
var to_display = number_suggested > 9 ? "9+" : number_suggested;
if (number_suggested > 0 && Admin.logged_in) {
Helper.removeClass(
document.querySelector(".suggested-link span.badge.new.white"),
"hide"
);
}
document.querySelector(
".suggested-link span.badge.new.white"
).innerText = to_display;
if (single) {
Suggestions.createSuggested(params);
} else {
for (var x in params) {
Suggestions.createSuggested(params[x]);
}
}
Suggestions.checkUserEmpty();
},
catchUserSuggests: function(params, single){
if(single) {
number_suggested = number_suggested + 1;
} else {
number_suggested = number_suggested + params.length;
}
for(var i = 0; i < params.length; i++) {
if(document.querySelectorAll("#suggested-" + params[i].id).length > 0) {
number_suggested -= 1;
}
}
var to_display = number_suggested > 9 ? "9+" : number_suggested;
if(number_suggested > 0 && Admin.logged_in){
Helper.removeClass(document.querySelector(".suggested-link span.badge.new.white"), "hide");
}
document.querySelector(".suggested-link span.badge.new.white").innerText = to_display;
if(single){
Suggestions.createSuggested(params);
}else{
for(var x in params){
Suggestions.createSuggested(params[x]);
}
}
Suggestions.checkUserEmpty();
},
createSuggested: function(params) {
var duration = Helper.secondsToOther(params.duration);
var video_id = params.id;
var video_title = params.title;
var date = new Date(params.added * 1000);
var addedTime =
Helper.pad(date.getDate()) +
"." +
Helper.pad(date.getMonth()) +
"." +
Helper.pad(date.getYear() - 100);
var toSend = {
id: video_id,
title: video_title,
length: params.duration,
duration: duration,
votes: addedTime,
extra: "Added"
};
if (params.added_by != undefined) {
toSend.extra += " by " + params.added_by;
}
if (params.source) toSend.source = params.source;
else {
toSend.source = "youtube";
}
if (params.thumbnail) toSend.thumbnail = params.thumbnail;
var song = List.generateSong(toSend, false, false, false, true);
var testingElem;
try {
testingElem = document.getElementById(video_id);
} catch (e) {}
createSuggested: function(params){
var duration = Helper.secondsToOther(params.duration);
var video_id = params.id;
var video_title = params.title;
var date = new Date(params.added * 1000);
var addedTime = Helper.pad(date.getHours()) + ":"
+ Helper.pad(date.getMinutes()) + " - "
+ Helper.pad(date.getDate()) + "."
+ Helper.pad(date.getMonth()) + "."
+ Helper.pad((date.getYear()-100));
var toSend = {id: video_id, title: video_title, length: params.duration, duration: duration, votes: addedTime, extra: "Added"};
if(params.source) toSend.source = params.source;
if(params.thumbnail) toSend.thumbnail = params.thumbnail;
var song = List.generateSong(toSend, false, false, false, true);
var testingElem;
try {
testingElem = document.getElementById(video_id);
} catch(e) {}
if (
!testingElem &&
document.querySelectorAll("#suggested-" + video_id).length == 0
) {
document
.getElementById("user-suggest-html")
.insertAdjacentHTML("beforeend", song);
}
},
if(!testingElem && document.querySelectorAll("#suggested-" + video_id).length == 0) {
document.getElementById("user-suggest-html").insertAdjacentHTML("beforeend", song);
}
},
fetchYoutubeSuggests: function(id) {
if (videoSource == "soundcloud") {
Helper.addClass(document.querySelector(".suggest-title-info"), "hide");
Helper.addClass("#suggest-song-html", "hide");
return;
} else {
Helper.removeClass(document.querySelector(".suggest-title-info"), "hide");
Helper.removeClass("#suggest-song-html", "hide");
}
var get_url =
"https://www.googleapis.com/youtube/v3/search?part=snippet&relatedToVideoId=" +
id +
"&type=video&key=" +
api_key.youtube;
var video_urls =
"https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id,statistics&fields=pageInfo,items(id,contentDetails,statistics(viewCount),snippet(categoryId,channelTitle,publishedAt,title,description,thumbnails))&key=" +
api_key.youtube +
"&id=";
fetchYoutubeSuggests: function(id){
if(videoSource == "soundcloud") {
Helper.addClass(document.querySelector(".suggest-title-info"), "hide");
Helper.addClass("#suggest-song-html", "hide");
return;
} else {
Helper.removeClass(document.querySelector(".suggest-title-info"), "hide");
Helper.removeClass("#suggest-song-html", "hide");
Helper.ajax({
type: "GET",
url: get_url,
dataType: "jsonp",
success: function(response) {
response = JSON.parse(response);
var this_resp = response.items.slice(0, 5);
for (var i = 0; i < this_resp.length; i++) {
var data = this_resp[i];
video_urls += data.id.videoId + ",";
}
var get_url = "https://www.googleapis.com/youtube/v3/search?part=snippet&relatedToVideoId="+id+"&type=video&key="+api_key.youtube;
var video_urls = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id,statistics&key="+api_key.youtube+"&id=";
Helper.ajax({
type: "GET",
url: get_url,
dataType:"jsonp",
success: function(response)
{
response = JSON.parse(response);
var this_resp = response.items.slice(0,5);
for(var i = 0; i < this_resp.length; i++) {
var data = this_resp[i];
video_urls += data.id.videoId+",";
}
type: "GET",
url: video_urls,
dataType: "jsonp",
success: function(response) {
response = JSON.parse(response);
Helper.setHtml("#suggest-song-html", "");
for (var i = 0; i < response.items.length; i++) {
var song = response.items[i];
var duration = song.contentDetails.duration;
var length = Search.durationToSeconds(duration);
duration = Helper.secondsToOther(
Search.durationToSeconds(duration)
);
var video_id = song.id;
var video_title = song.snippet.title;
var viewCount = 0;
try {
viewCount = song.statistics.viewCount
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, " ");
} catch (e) {}
Helper.ajax({
type: "GET",
url: video_urls,
dataType: "jsonp",
success: function(response)
try {
document.getElementById("suggest-song-html").insertAdjacentHTML(
"beforeend",
List.generateSong(
{
response = JSON.parse(response);
Helper.setHtml("#suggest-song-html", "");
for(var i = 0; i < response.items.length; i++) {
var song = response.items[i];
var duration = song.contentDetails.duration;
var length = Search.durationToSeconds(duration);
duration = Helper.secondsToOther(Search.durationToSeconds(duration));
var video_id = song.id;
var video_title = song.snippet.title;
var viewCount = song.statistics.viewCount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
try {
document.getElementById("suggest-song-html").insertAdjacentHTML("beforeend", List.generateSong({id: video_id, title: video_title, length: length, duration: duration, votes: viewCount, extra: "Views"}, false, false, false));
} catch(e) {}
}
}
});
id: video_id,
title: video_title,
length: length,
duration: duration,
votes: viewCount,
extra: "Views",
source: "youtube"
},
false,
false,
false
)
);
} catch (e) {}
}
}
});
},
}
});
},
checkUserEmpty: function(){
var length = document.getElementById("user-suggest-html").children.length;
if(length === 0){
Helper.addClass("#user_suggests", "hide");
} else if(Admin.logged_in){
Helper.removeClass("#user_suggests", "hide");
}
},
checkUserEmpty: function() {
var length = document.getElementById("user-suggest-html").children.length;
if (length === 0) {
Helper.addClass("#user_suggests", "hide");
} else if (Admin.logged_in) {
Helper.removeClass("#user_suggests", "hide");
}
}
};

View File

@@ -1,60 +1,87 @@
window.addEventListener("DOMContentLoaded", function(e) {
M.Modal.init(document.getElementById("about"));
M.Modal.init(document.getElementById("contact"));
Helper.addClass(".help-button-footer", "hide");
M.Modal.init(document.getElementById("about"));
M.Modal.init(document.getElementById("contact"));
Helper.addClass(".help-button-footer", "hide");
Helper.setHtml("#contact-container", "");
Helper.setHtml("#contact-container", "Send a mail to us: <a title='Open in client' href='mailto:contact@zoff.me?Subject=Contact%20Zoff'>contact@zoff.me</a>");
Helper.css("#submit-contact-form", "display", "none");
Helper.setHtml("#contact-container", "");
Helper.setHtml(
"#contact-container",
"Send a mail to us: <a title='Open in client' href='mailto:contact@zoff.me?Subject=Contact%20Zoff'>contact@zoff.me</a>"
);
Helper.css("#submit-contact-form", "display", "none");
ga('send', 'pageview');
var page = window.location.pathname;
if (page.substring(page.length - 1) != "/") page += "/";
ga("send", "pageview", page);
if(!Helper.mobilecheck()) {
if(document.querySelector("#iframe-container")) {
document.getElementById("iframe-container").insertAdjacentHTML("beforeend", '<iframe id="iframe" src="https://zoff.me/_embed#celebrate&808080&autoplay" width="600px" height="300px" allow="autoplay"></iframe>');
}
if (!Helper.mobilecheck()) {
if (document.querySelector("#iframe-container")) {
document
.getElementById("iframe-container")
.insertAdjacentHTML(
"beforeend",
'<iframe id="iframe" src="https://zoff.me/_embed#celebrate&808080&autoplay" width="600px" height="300px" allow="autoplay"></iframe>'
);
}
}
document.getElementsByClassName("token-form")[0].addEventListener("submit", function(e) {
e.preventDefault();
var email = document.getElementById("email_address").value;
var origin = document.getElementById("origin").value;
document.getElementById("origin").setAttribute("readonly", true);
document.getElementById("email_address").setAttribute("readonly", true);
Helper.toggleClass(".submit", "disabled");
Helper.removeClass(".full-form-token", "hide");
var captcha_response = grecaptcha.getResponse();
Helper.ajax({
type: "POST",
url: "/api/apply",
headers: {"Content-Type": "application/json;charset=UTF-8"},
data: {
origin: origin,
email: email,
"g-recaptcha-response": captcha_response,
},
success: function(response) {
Helper.addClass(".full-form-token", "hide");
if(response == "success") {
M.toast({html: "Email sent!", displayLength: 3000, classes: "green lighten"});
} else {
document.getElementById("email_address").setAttribute("readonly", false);
Helper.toggleClass(".submit", "disabled");
document.getElementById("origin").setAttribute("readonly", false);
grecaptcha.reset();
M.toast({html: "Something went wrong. Sure that email hasn't been used for another token?",displayLength: 3000, classes: "red lighten"});
}
},
error: function(response) {
Helper.addClass(".full-form-token", "hide");
document.getElementById("email_address").setAttribute("readonly", false);
Helper.toggleClass(".submit", "disabled");
}
});
document
.getElementsByClassName("token-form")[0]
.addEventListener("submit", function(e) {
e.preventDefault();
var email = document.getElementById("email_address").value;
var origin = document.getElementById("origin").value;
document.getElementById("origin").setAttribute("readonly", true);
document.getElementById("email_address").setAttribute("readonly", true);
Helper.toggleClass(".submit", "disabled");
Helper.removeClass(".full-form-token", "hide");
var captcha_response = grecaptcha.getResponse();
Helper.ajax({
type: "POST",
url: "/api/apply",
headers: { "Content-Type": "application/json;charset=UTF-8" },
data: {
origin: origin,
email: email,
"g-recaptcha-response": captcha_response
},
success: function(response) {
Helper.addClass(".full-form-token", "hide");
if (response == "success") {
M.toast({
html: "Email sent!",
displayLength: 3000,
classes: "green lighten"
});
} else {
document
.getElementById("email_address")
.setAttribute("readonly", false);
Helper.toggleClass(".submit", "disabled");
document.getElementById("origin").setAttribute("readonly", false);
grecaptcha.reset();
M.toast({
html:
"Something went wrong. Sure that email hasn't been used for another token?",
displayLength: 3000,
classes: "red lighten"
});
}
},
error: function(response) {
Helper.addClass(".full-form-token", "hide");
document
.getElementById("email_address")
.setAttribute("readonly", false);
Helper.toggleClass(".submit", "disabled");
}
});
});
document.getElementById('submit-contact-form').addEventListener('click', function(e) {
e.preventDefault();
document.getElementById("contact-form").submit();
document
.getElementById("submit-contact-form")
.addEventListener("click", function(e) {
e.preventDefault();
document.getElementById("contact-form").submit();
});
});

View File

@@ -1,36 +1,36 @@
{
"short_name": "Zoff",
"name": "Zoff",
"description": "A free YouTube based radio, where no registration is needed for listening to channels, or creating your own channels. ",
"dir": "ltr",
"lang": "en-US",
"start_url": "/",
"display": "standalone",
"background_color": "#2D2D2D",
"theme_color": "#2D2D2D",
"orientation": "portrait",
"related_applications": [
{
"platform": "play",
"id": "zoff.me.zoff",
"url": "https://play.google.com/store/apps/details?id=zoff.me.zoff"
},
{
"platform": "itunes",
"id": "me.zoff.zoffnative",
"url": "https://itunes.apple.com/us/app/zoff/id1402037061?ls=1&mt=8"
}
],
"icons": [
{
"src": "/assets/images/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/assets/images/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
"short_name": "Zoff",
"name": "Zoff",
"description": "A free YouTube based radio, where no registration is needed for listening to channels, or creating your own channels. ",
"dir": "ltr",
"lang": "en-US",
"start_url": "/",
"display": "standalone",
"background_color": "#2D2D2D",
"theme_color": "#2D2D2D",
"orientation": "portrait",
"related_applications": [
{
"platform": "play",
"id": "zoff.me.zoff",
"url": "https://play.google.com/store/apps/details?id=zoff.me.zoff"
},
{
"platform": "itunes",
"id": "me.zoff.zoffnative",
"url": "https://itunes.apple.com/us/app/zoff/id1402037061?ls=1&mt=8"
}
],
"icons": [
{
"src": "/assets/images/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/assets/images/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}

View File

@@ -0,0 +1 @@
var SC=SC||{};SC.Widget=function(n){function t(r){if(e[r])return e[r].exports;var o=e[r]={exports:{},id:r,loaded:!1};return n[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var e={};return t.m=n,t.c=e,t.p="",t(0)}([function(n,t,e){function r(n){return!!(""===n||n&&n.charCodeAt&&n.substr)}function o(n){return!!(n&&n.constructor&&n.call&&n.apply)}function i(n){return!(!n||1!==n.nodeType||"IFRAME"!==n.nodeName.toUpperCase())}function a(n){var t,e=!1;for(t in b)if(b.hasOwnProperty(t)&&b[t]===n){e=!0;break}return e}function s(n){var t,e,r;for(t=0,e=I.length;t<e&&(r=n(I[t]),r!==!1);t++);}function u(n){var t,e,r,o="";for("//"===n.substr(0,2)&&(n=window.location.protocol+n),r=n.split("/"),t=0,e=r.length;t<e&&t<3;t++)o+=r[t],t<2&&(o+="/");return o}function c(n){return n.contentWindow?n.contentWindow:n.contentDocument&&"parentWindow"in n.contentDocument?n.contentDocument.parentWindow:null}function l(n){var t,e=[];for(t in n)n.hasOwnProperty(t)&&e.push(n[t]);return e}function d(n,t,e){e.callbacks[n]=e.callbacks[n]||[],e.callbacks[n].push(t)}function E(n,t){var e,r=!0;return t.callbacks[n]=[],s(function(t){if(e=t.callbacks[n]||[],e.length)return r=!1,!1}),r}function f(n,t,e){var r,o,i=c(e);return!!i.postMessage&&(r=e.getAttribute("src").split("?")[0],o=JSON.stringify({method:n,value:t}),"//"===r.substr(0,2)&&(r=window.location.protocol+r),r=r.replace(/http:\/\/(w|wt).soundcloud.com/,"https://$1.soundcloud.com"),void i.postMessage(o,r))}function p(n){var t;return s(function(e){if(e.instance===n)return t=e,!1}),t}function h(n){var t;return s(function(e){if(c(e.element)===n)return t=e,!1}),t}function v(n,t){return function(e){var r=o(e),i=p(this),a=!r&&t?e:null,s=r&&!t?e:null;return s&&d(n,s,i),f(n,a,i.element),this}}function S(n,t,e){var r,o,i;for(r=0,o=t.length;r<o;r++)i=t[r],n[i]=v(i,e)}function R(n,t,e){return n+"?url="+t+"&"+g(e)}function g(n){var t,e,r=[];for(t in n)n.hasOwnProperty(t)&&(e=n[t],r.push(t+"="+("start_track"===t?parseInt(e,10):e?"true":"false")));return r.join("&")}function m(n,t,e){var r,o,i=n.callbacks[t]||[];for(r=0,o=i.length;r<o;r++)i[r].apply(n.instance,e);(a(t)||t===L.READY)&&(n.callbacks[t]=[])}function z(n){var t,e,r,o,i;try{e=JSON.parse(n.data);if(!e.hasOwnProperty("method"))return!1}catch(a){return!1}return t=h(n.source),r=e.method,o=e.value,(!t||A(n.origin)===A(t.domain))&&(t?(r===L.READY&&(t.isReady=!0,m(t,C),E(C,t)),r!==L.PLAY||t.playEventFired||(t.playEventFired=!0),r!==L.PLAY_PROGRESS||t.playEventFired||(t.playEventFired=!0,m(t,L.PLAY,[o])),i=[],void 0!==o&&i.push(o),void m(t,r,i)):(r===L.READY&&T.push(n.source),!1))}function A(n){return n.replace(Y,"")}var _,y,O,D=e(1),b=e(2),P=e(3),L=D.api,N=D.bridge,T=[],I=[],C="__LATE_BINDING__",k="http://wt.soundcloud.test:9200/",Y=/^http(?:s?)/;window.addEventListener?window.addEventListener("message",z,!1):window.attachEvent("onmessage",w),n.exports=O=function(n,t,e){if(r(n)&&(n=document.getElementById(n)),!i(n))throw new Error("SC.Widget function should be given either iframe element or a string specifying id attribute of iframe element.");t&&(e=e||{},n.src=R(k,t,e));var o,a,s=h(c(n));return s&&s.instance?s.instance:(o=T.indexOf(c(n))>-1,a=new _(n),I.push(new y(a,n,o)),a)},O.Events=L,window.SC=window.SC||{},window.SC.Widget=O,y=function(n,t,e){this.instance=n,this.element=t,this.domain=u(t.getAttribute("src")),this.isReady=!!e,this.callbacks={}},_=function(){},_.prototype={constructor:_,load:function(n,t){if(n){t=t||{};var e=this,r=p(this),o=r.element,i=o.src,a=i.substr(0,i.indexOf("?"));r.isReady=!1,r.playEventFired=!1,o.onload=function(){e.bind(L.READY,function(){var n,e=r.callbacks;for(n in e)e.hasOwnProperty(n)&&n!==L.READY&&f(N.ADD_LISTENER,n,r.element);t.callback&&t.callback()})},o.src=R(a,n,t)}},bind:function(n,t){var e=this,r=p(this);return r&&r.element&&(n===L.READY&&r.isReady?setTimeout(t,1):r.isReady?(d(n,t,r),f(N.ADD_LISTENER,n,r.element)):d(C,function(){e.bind(n,t)},r)),this},unbind:function(n){var t,e=p(this);e&&e.element&&(t=E(n,e),n!==L.READY&&t&&f(N.REMOVE_LISTENER,n,e.element))}},S(_.prototype,l(b)),S(_.prototype,l(P),!0)},function(n,t){t.api={LOAD_PROGRESS:"loadProgress",PLAY_PROGRESS:"playProgress",PLAY:"play",PAUSE:"pause",FINISH:"finish",SEEK:"seek",READY:"ready",OPEN_SHARE_PANEL:"sharePanelOpened",CLICK_DOWNLOAD:"downloadClicked",CLICK_BUY:"buyClicked",ERROR:"error"},t.bridge={REMOVE_LISTENER:"removeEventListener",ADD_LISTENER:"addEventListener"}},function(n,t){n.exports={GET_VOLUME:"getVolume",GET_DURATION:"getDuration",GET_POSITION:"getPosition",GET_SOUNDS:"getSounds",GET_CURRENT_SOUND:"getCurrentSound",GET_CURRENT_SOUND_INDEX:"getCurrentSoundIndex",IS_PAUSED:"isPaused"}},function(n,t){n.exports={PLAY:"play",PAUSE:"pause",TOGGLE:"toggle",SEEK_TO:"seekTo",SET_VOLUME:"setVolume",NEXT:"next",PREV:"prev",SKIP:"skip"}}]);

View File

@@ -11,194 +11,219 @@
</nav>
</header>
<main class="container center-align admin_panel">
<div class="row">
<h2 class="col s11">Admin</h2>
<a href="#" id="refresh_all" class="col s1"><h2><i class="material-icons">refresh</i></h2></a>
</div>
<div class="row">
<div class="col s12 m10">
<ul class="tabs tabs_admin">
<li class="tab col s2"><a class="active" href="#general">General</a></li>
<li class="tab col s2"><a href="#api_keys">API<span class="new admin-panel hide"></span></a></li>
<li class="tab col s3"><a href="#thumbnails">Thumbnails<span class="new thumbnails-badge badge admin-panel hide"></span></a></li>
<li class="tab col s3"><a href="#descriptions">Descriptions<span class="new descriptions-badge badge admin-panel hide"></span></a></li>
<li class="tab col s2"><a href="#names">Names</a></li>
</ul>
<div id="general" class="col s12">
<div class="preloader-wrapper big active">
<div class="spinner-layer spinner-zoff-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div><div class="gap-patch">
<div class="circle"></div>
</div><div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
<div class="channel_things hide">
<form id="change_pinned">
<div class="row">
<div class="input-field col s8 m10">
<select id="frontpage_pinned">
<option value="" disabled>Channels</option>
</select>
<label>Change Pinned</label>
</div>
<div class="col s2">
<a href="#" id="change_pinned_button" class="btn green waves-effect">UPDATE</a>
</div>
</div>
</form>
<form id="delete_list">
<div class="row">
<div class="input-field col s8 m10">
<select id="delete_list_name">
<option value="" disabled>Channels</option>
</select>
<label>Delete Admin</label>
</div>
<div class="col s2">
<a href="#" id="delete_admin_button" class="btn orange waves-effect">UPDATE</a>
</div>
</div>
</form>
<form id="delete_userpass">
<div class="row">
<div class="input-field col s8 m10">
<select id="delete_userpass_name">
<option value="" disabled>Channels</option>
</select>
<label>Delete Userpass</label>
</div>
<div class="col s2">
<a href="#" id="delete_userpass_button" class="btn blue waves-effect">UPDATE</a>
</div>
</div>
</form>
<form id="delete_channel">
<div class="row">
<div class="input-field col s8 m10">
<select id="delete_channel_name">
<option value="" disabled>Channels</option>
</select>
<label>Delete Channel</label>
</div>
<div class="col s2">
<a href="#" id="delete_channel_button" class="btn red waves-effect">DELETE</a>
</div>
</div>
</form>
<div class="row">
<h2 class="col s11">Admin</h2>
<a href="#" id="refresh_all" class="col s1"><h2><i class="material-icons">refresh</i></h2></a>
</div>
<div class="row">
<div class="col s12 m10">
<ul class="tabs tabs_admin">
<li class="tab col s3"><a class="active" href="#general">General</a></li>
<li class="tab col s3"><a href="#api_keys">API<span class="new admin-panel hide"></span></a></li>
<li class="tab col s3"><a href="#info">Info<span class="new info-badge badge admin-panel hide"></span></a></li>
<li class="tab col s3"><a href="#names">Names</a></li>
</ul>
<div id="general" class="col s12">
<div class="preloader-wrapper big active">
<div class="spinner-layer spinner-zoff-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div><div class="gap-patch">
<div class="circle"></div>
</div><div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
<div class="channel_things hide">
<form id="change_pinned">
<div class="row">
<div class="input-field col s8 m10">
<select id="frontpage_pinned">
<option value="" disabled>Channels</option>
</select>
<label>Change Pinned</label>
</div>
<div class="col s2">
<a href="#" id="change_pinned_button" class="btn green waves-effect">UPDATE</a>
</div>
</div>
</form>
<form id="delete_list">
<div class="row">
<div class="input-field col s8 m10">
<select id="delete_list_name">
<option value="" disabled>Channels</option>
</select>
<label>Delete Admin</label>
</div>
<div class="col s2">
<a href="#" id="delete_admin_button" class="btn orange waves-effect">UPDATE</a>
</div>
</div>
</form>
<form id="delete_userpass">
<div class="row">
<div class="input-field col s8 m10">
<select id="delete_userpass_name">
<option value="" disabled>Channels</option>
</select>
<label>Delete Userpass</label>
</div>
<div class="col s2">
<a href="#" id="delete_userpass_button" class="btn blue waves-effect">UPDATE</a>
</div>
</div>
</form>
<form id="delete_channel">
<div class="row">
<div class="input-field col s8 m10">
<select id="delete_channel_name">
<option value="" disabled>Channels</option>
</select>
<label>Delete Channel</label>
</div>
<div class="col s2">
<a href="#" id="delete_channel_button" class="btn red waves-effect">DELETE</a>
</div>
</div>
</form>
<div class="row">
<div class="input-field col s8 m10">
<input type="text" readonly id="new_token" />
<div class="row">
<div class="input-field col s8 m10">
<input type="text" readonly id="new_token" />
</div>
<div class="col s2">
<a href="#" id="get_token" class="btn waves-effect">TOKEN</a>
<a href="#" id="remove_token" class="btn red waves-effect hide">REMOVE</a>
</div>
</div>
</div>
</div>
<div class="col s2">
<a href="#" id="get_token" class="btn waves-effect">TOKEN</a>
<a href="#" id="remove_token" class="btn red waves-effect hide">REMOVE</a>
<div id="api_keys" class="col s12" style="display:none;">
<div class="row header-api-fields">
<div class="col s3">
Name
</div>
<div class="col s3">
Origin
</div>
<div class="col s1">
Usage
</div>
<div class="col s1">
Limit
</div>
</div>
<div class="row api_token_container" id="api_token_list">
<div class="col s3 api_token_name truncate">
</div>
<div class="col s3 api_token_origin truncate">
</div>
<div class="col s1 api_token_usage">
</div>
<input class="api_token_limit col s1" type="number" />
<div class="col s1 api_token_activated">
<i class="material-icons check hide">check</i>
<i class="material-icons uncheck hide">close</i>
</div>
<a href="#" class="btn waves-effect green col s1 update_api_token"><i class="material-icons check">check</i></a>
<a href="#" class="btn waves-effect red col s1 delete_api_token">X</a>
</div>
</div>
</div>
</div>
</div>
<div id="api_keys" class="col s12" style="display:none;">
<div class="row header-api-fields">
<div class="col s3">
Name
</div>
<div class="col s3">
Origin
</div>
<div class="col s1">
Usage
</div>
<div class="col s1">
Limit
</div>
</div>
<div class="row api_token_container" id="api_token_list">
<div class="col s3 api_token_name truncate">
</div>
<div class="col s3 api_token_origin truncate">
</div>
<div class="col s1 api_token_usage">
</div>
<input class="api_token_limit col s1" type="number" />
<div class="col s1 api_token_activated">
<i class="material-icons check hide">check</i>
<i class="material-icons uncheck hide">close</i>
<div id="info" class="col s12" style="display:none;">
<div class="row">
<div class="col s12 tabs_margin">
<ul class="tabs tabs_admin_info">
<li class="tab col s4"><a class="active" href="#thumbnails">Thumbnails<span class="new thumbnails-badge badge admin-panel hide"></span></a></li>
<li class="tab col s4"><a href="#descriptions">Descriptions<span class="new descriptions-badge badge admin-panel hide"></span></a></li>
<li class="tab col s4"><a href="#rules">Rules<span class="new rules-badge badge admin-panel hide"></span></a></li>
</ul>
</div>
<div id="thumbnails" class="col s12">
<div class="row">
<div class="input-field col s8 m10">
<select id="remove_thumbnail">
<option value="" disabled>Channels</option>
</select>
<label>Remove Thumbnail</label>
</div>
<div class="col s2">
<a href="#" id="remove_thumbnail_button" class="btn red waves-effect">REMOVE</a>
</div>
<div id="thumbnails_cont" class="col s12">
</div>
</div>
</div>
<div id="descriptions" class="col s12">
<div class="row">
<div class="input-field col s8 m10">
<select id="remove_description">
<option value="" disabled>Channels</option>
</select>
<label>Remove Description</label>
</div>
<div class="col s2">
<a href="#" id="remove_description_button" class="btn red waves-effect">REMOVE</a>
</div>
</div>
<div id="descriptions_cont" class="col s12">
</div>
</div>
<div id="rules" class="col s12">
<div class="row">
<div class="input-field col s8 m10">
<select id="remove_rules">
<option value="" disabled>Channels</option>
</select>
<label>Remove Rules</label>
</div>
<div class="col s2">
<a href="#" id="remove_rules_button" class="btn red waves-effect">REMOVE</a>
</div>
</div>
<div id="rules_cont" class="col s12">
</div>
</div>
</div>
</div>
<a href="#" class="btn waves-effect green col s1 update_api_token"><i class="material-icons check">check</i></a>
<a href="#" class="btn waves-effect red col s1 delete_api_token">X</a>
</div>
</div>
<div id="thumbnails" class="col s12" style="display:none;">
<div class="row">
<div class="input-field col s8 m10">
<select id="remove_thumbnail">
<option value="" disabled>Channels</option>
</select>
<label>Remove Thumbnail</label>
</div>
<div class="col s2">
<a href="#" id="remove_thumbnail_button" class="btn red waves-effect">REMOVE</a>
</div>
<div id="thumbnails_cont" class="col s12">
</div>
</div>
</div>
<div id="descriptions" class="col s12" style="display:none;">
<div class="row">
<div class="input-field col s8 m10">
<select id="remove_description">
<option value="" disabled>Channels</option>
</select>
<label>Remove Description</label>
</div>
<div class="col s2">
<a href="#" id="remove_description_button" class="btn red waves-effect">REMOVE</a>
</div>
</div>
<div id="descriptions_cont" class="col s12">
</div>
</div>
<div id="names" class="col s12" style="display:none;">
<div class="row names-container">
<div id="names" class="col s12">
<div class="row names-container">
</div>
</div>
</div>
<div class="col s10 m2 left-align" id="listeners">
<div class="row">
</div>
</div>
</div>
</div>
<div class="col s10 m2 left-align" id="listeners">
<div class="row">
</div>
</div>
</div>
</main>
<footer class="page-footer cursor-default">
<div class="container">
<div class="row">
<div class="col l6 s12">
<h5 class="white-text">Zoff</h5>
<p class="grey-text text-lighten-4">The shared YouTube and SoundCloud radio</p>
<p class="grey-text text-lighten-4">
Being built around the YouTube and SoundCloud API
it enables the creation of collaborative and shared live playlists,
with billions of videos and songs to choose from, all for free and without registration.
<br />
Enjoy!
</p>
</div>
<div class="col l4 offset-l2 s12 valign-wrapper">
</div>
</div>
</div>
<div class="footer-copyright">
<div class="container">
&copy; {{year}}
<a href="http://nixo.no">Nixo</a> &amp;
<a href="http://kasperrt.no">KasperRT</a>
<br>
All Rights Reserved.
<div class="row">
<div class="col l6 s12">
<h5 class="white-text">Zoff</h5>
<p class="grey-text text-lighten-4">The shared YouTube and SoundCloud radio</p>
<p class="grey-text text-lighten-4">
Being built around the YouTube and SoundCloud API
it enables the creation of collaborative and shared live playlists,
with billions of videos and songs to choose from, all for free and without registration.
<br />
Enjoy!
</p>
</div>
<div class="col l4 offset-l2 s12 valign-wrapper">
</div>
</div>
</div>
<div class="footer-copyright">
<div class="container">
&copy; {{year}}
<a href="http://kasperrt.no">KasperRT</a> &amp;
<a href="http://nixo.no">Nixo</a>
<br>
All Rights Reserved.
</div>
</div>
</div>
</footer>

View File

@@ -15,10 +15,10 @@
<meta property="og:description" content="Zoff admin panel">
<meta property="og:type" content="website">
<link rel="icon" id="favicon" type="image/png" href="https://zoff.me/assets/images/favicon.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/css/materialize.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/js/materialize.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://zoff.me/assets/css/style.css" title="Default" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
@@ -48,11 +48,11 @@
margin-right: 2px;
}
.tabs_admin{
.tabs_admin, .tabs_margin{
margin-bottom:20px;
}
.tabs_admin .indicator{
.tabs_admin .indicator, .tabs_admin_info .indicator{
width: initial !important;
background: black !important;
}

View File

@@ -6,7 +6,7 @@
<div class="modal-footer">
</div>
</div>
<div id="song-title"></div>
<div id="song-title" class="truncate" style="display:block;">Loading..</div>
<div id="main_components" style="display:inline-flex;">
<div id="player-container">
<div id="player"></div>
@@ -23,7 +23,10 @@
</div>
</div>
</div>
<div id="zoffbutton" title="Visit the channel!"></div>
<a href="https://zoff.me" class="channel-info-container" title="Visit the channel!">
<div id="zoffbutton"></div>
<div class="channel-title white-text"></div>
</a>
<div id="controls" class="noselect">
<div class="playbar-btn prev playbar hide">
<i class="material-icons">skip_previous</i>
@@ -32,7 +35,7 @@
<i id="play" class="material-icons hide">play_arrow</i>
<i id="pause" class="material-icons">pause</i>
</div>
<div class="playbar-btn skip playbar hide">
<div class="playbar-btn skip playbar">
<i class="material-icons">skip_next</i>
</div>
<div id="duration">00:00 / 00:00</div>
@@ -49,9 +52,6 @@
</div>
<div id="playlist">
<div id="wrapper">
<div id="preloader" class="progress channel_preloader">
<div class="indeterminate"></div>
</div>
<div id="list-song-html">
<div id="list-song" class="card left-align list-song waves-effect waves-light playlist-element">
<div class="clickable vote-container" title="Vote!">
@@ -101,4 +101,9 @@
</span>
</div>
</div>
<div class="site_loader">
<div class="preloader-wrapper large active valign">
{{> spinner}}
</div>
</div>
</div>

View File

@@ -20,7 +20,7 @@
<meta property="og:url" content="https://zoff.me" />
<meta property="og:title" content="Zoff"/>
<meta property="og:description" content="The Shared (free) YouTube and SoundCloud radio."/>
<meta property="og:type" content="website"/>
<meta property="og:type" content="{{type}}"/>
<meta property="fb:app_id" content="1581693815380949" />
<link rel="manifest" href="/assets/manifest.json">
{{#unless embed}}
@@ -29,7 +29,7 @@
<link rel="icon" id="favicon" type="image/png" sizes="16x16" href="/assets/images/favicon-16x16.png">
<link rel="mask-icon" href="/assets/images/safari-pinned-tab.svg" color="#2d2d2d">
{{/unless}}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/css/materialize.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link rel="stylesheet" type="text/css" href="/assets/dist/{{stylesheet}}">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" media="none" onload="if(media!='all')media='all'">
{{#unless embed}}
@@ -47,6 +47,15 @@
}
}
</script>
{{#if adds}}
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script>
(adsbygoogle = window.adsbygoogle || []).push({
google_ad_client: "{{{ adsense }}}",
enable_page_level_ads: true
});
</script>
{{/if}}
{{/unless}}
</head>
<body class="noselect">
@@ -80,7 +89,7 @@
</ul>
<div id="context-menu-overlay" class="hide"></div>
{{/unless}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/js/materialize.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.0/socket.io.slim.js"></script>
<script type="text/javascript" src="/assets/dist/{{javascript_file}}"></script>
{{#unless embed}}

View File

@@ -18,8 +18,9 @@
</li>
<li id="chat-input" class="row">
<form action="#" id="chatForm">
<input id="text-chat-input" class="col s9" name="input" type="text" autocomplete="off" placeholder="Chat" maxlength="150" />
<input id="text-chat-input" class="col s8" name="input" type="text" autocomplete="off" placeholder="Chat" maxlength="150" />
<a href="#" id="chat_submit" class="btn col s2 white waves-effect"><i class="material-icons">send</i></a>
<a href="#" id="chat_help" class="btn col s2 white waves-effect"><i class="material-icons">help</i></a>
</form>
</li>
</ul>

View File

@@ -0,0 +1,93 @@
<li class="no-padding">
<div class="collapsible-header bold waves-effect">Client Settings
<i class="material-icons">settings</i>
</div>
<div class="collapsible-body info_collapsible">
<ul>
<li class="">
<span class="switch-text">
Intelligent
</span>
<div class="switch">
<label>
Disabled
<input name="intelligent_switch" type="checkbox" class="intelligent_switch_class" checked /><span class="lever"></span>
Enabled
</label>
</div>
</li>
{{#unless client}}
<li class="hide-on-small-only hide-on-mobile-only">
<span class="switch-text">
Remote
</span>
<div class="switch">
<label>
Disabled
<input name="remote_switch" type="checkbox" class="remote_switch_class" checked /><span class="lever"></span>
Enabled
</label>
</div>
</li>
<li>
<span class="switch-text">
Local Mode
</span>
<div class="switch">
<label>
Disabled
<input name="offline_switch" type="checkbox" class="offline_switch_class" /><span class="lever"></span>
Enabled
</label>
</div>
</li>
{{/unless}}
<li>
<span class="switch-text">
Background
</span>
<div class="switch">
<label>
Static
<input name="background_switch" type="checkbox" checked class="backround_switch_class" /><span class="lever"></span>
Dynamic
</label>
</div>
</li>
<li>
<span class="switch-text">
Cast info
</span>
<div class="switch">
<label>
Hide
<input name="chromecast_info_display" type="checkbox" checked class="chromecast_info_display_class" /><span class="lever"></span>
&nbsp;&nbsp;&nbsp;Show
</label>
</div>
</li>
<li class="background_color_container hide">
<div class="row">
<span class="col switch-text">Color</span>
<div class="col offset-s5">
<input type="color" id="background_color_choser" class="settings_embed" value="#2d2d2d" />
</div>
</div>
</li>
<li>
<div class="row">
<div class="col s10 offset-s1">
<p class="initial-line-height">
When enabling intelligent playlist, playlist elements are not updated and moved around when the playlist is in focus. If things are jumping too much around in the playlist when voting, you should enable this.
</p>
{{#unless client}}
<p class="initial-line-height">
By enabling local mode, you won't receive updates in position of the currently playing song, you'll be able to vote as many times as you please, and you can skip to a specific location in the song.
</p>
{{/unless}}
</div>
</div>
</li>
</ul>
</div>
</li>

View File

@@ -13,7 +13,7 @@
Loading...
</li>
<li class="search-container hide" id="search-wrapper">
<input id="search" class="search_input white-text" type="text" title="Search for songs..." placeholder="Find song on YouTube or SoundCloud..." onsubmit="null;" autocomplete="off" />
<input id="search" class="search_input white-text" type="text" title="Search for songs..." placeholder="Search.." onsubmit="null;" autocomplete="off" />
</li>
</ul>
<ul class="right control-list noselect">

View File

@@ -1,42 +1,69 @@
{{#unless client}}
<div id="embed" class="modal">
<div class="modal-content">
<h4>Embed</h4>
<p>Copy the code in the textarea, and paste on your website.</p>
<p>
<label>
<input type="checkbox" id="autoplay" checked="checked" />
<span for="autoplay" class="padding_right_26">Autoplay</span>
</label>
<label for="width_embed" class="embed-label">Width</label>
<input type="number" value="600" id="width_embed" class="settings_embed" min="1" />
<label for="height_embed" class="padding_left_6 embed-label">Height</label>
<input type="number" value="300" id="height_embed" class="settings_embed" min="1" />
<label for="color_embed" class="padding_left_6 embed-label">Color</label>
<input type="color" id="color_embed" class="settings_embed" value="#808080" />
<label>
<input type="checkbox" id="videoonly" class="checkbox" />
<span for="videoonly" class="padding_right_26">Video-only</span>
</label>
<label>
<input type="checkbox" id="localmode" class="checkbox" />
<span for="localmode" class="padding_right_26">Local-mode</span>
</label>
</p>
<textarea id="embed-area"></textarea>
</div>
<div class="modal-footer">
<a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Close</a>
</div>
<div id="embed" class="modal">
<div class="modal-content">
<h4>Embed</h4>
<p>Copy the code in the textarea, and paste on your website.</p>
<p>
<label>
<input type="checkbox" id="autoplay" checked="checked" />
<span for="autoplay" class="padding_right_26">Autoplay</span>
</label>
<label for="width_embed" class="embed-label">Width</label>
<input type="number" value="600" id="width_embed" class="settings_embed" min="1" />
<label for="height_embed" class="padding_left_6 embed-label">Height</label>
<input type="number" value="400" id="height_embed" class="settings_embed" min="1" />
<label for="color_embed" class="padding_left_6 embed-label">Color</label>
<input type="color" id="color_embed" class="settings_embed" value="#2d2d2d" />
<label>
<input type="checkbox" id="videoonly" class="checkbox" />
<span for="videoonly" class="padding_right_26">Video-only</span>
</label>
<label>
<input type="checkbox" id="localmode" class="checkbox" />
<span for="localmode" class="padding_right_26">Local-mode</span>
</label>
</p>
<textarea id="embed-area"></textarea>
<div class="embed-preview"></div>
</div>
<div id="channel-share-modal" class="modal">
<div class="modal-content">
<p>To join this channel, go to</p>
<p><span id="channel-name-join"></span></p>
<img id="share-join-qr" alt="QR code for joining" title="Link to join this Zoff channel" src="https://chart.googleapis.com/chart?chs=221x221&amp;cht=qr&amp;choe=UTF-8&amp;chld=L%7C1&amp;chl=http://zoff.me" />
</div>
<div class="modal-footer">
<a href="#!" class="waves-effect waves-green btn-flat preview-embed">Preview</a>
<a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Close</a>
</div>
</div>
<div id="channel-share-modal" class="modal">
<div class="modal-content">
<p>To join this channel, go to</p>
<p><span id="channel-name-join"></span></p>
<img id="share-join-qr" alt="QR code for joining" title="Link to join this Zoff channel" src="https://chart.googleapis.com/chart?chs=221x221&amp;cht=qr&amp;choe=UTF-8&amp;chld=L%7C1&amp;chl=http://zoff.me" />
</div>
</div>
{{/unless}}
<div id="advanced_filter" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>Advanced</h4>
<p>Here you can search by category. Keep in mind, this uses the category/genre/tags defined by the uploader of the video on YouTube or the song on SoundCloud</p>
<div class="row container">
<form id="filter-form">
<input type="text" class="col s4 m5" name="filtersearch_value" placeholder="Find.." id="filtersearch_input" autocomplete="off" />
<div class="input-field col s4 m3 category-advanced">
<select class="category-advanced-select">
<option value="" disabled>Type</option>
<option value="category" selected>Category</option>
<option value="title">Title</option>
</select>
</div>
<input type="submit" class="hide" />
<a href="#" class="waves-effect waves-light btn col s4 m3 orange submit-filter-search">Search</a>
</form>
</div>
<div class="filter-results">
</div>
</div>
<div class="modal-footer">
<a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Close</a>
</div>
</div>
<div id="help" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>Help</h4>
@@ -53,6 +80,43 @@
<a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Close</a>
</div>
</div>
<div id="channel_info" class="modal">
<div class="modal-content">
<h5>Channel Info</h5>
<p>Here you can add a thumbnail for the channel, description or rules. The description and thumbnail will be visible from the frontpage, and the sidebar, but the rules will only be visible from the sidebar when in the channel.</p>
<p>Remember, all thumbnails, descriptions and rules has to be approved by a site-administrator before it will be visible to visitors.</p>
<div class="row">
<form id="thumbnail_input_form" class="col s12">
<div class="input-field col s8">
<input id="thumbnail_input" name="user-pass" type="text" autocomplete="off" />
<label for="thumbnail_input" class="noselect">Thumbnail</label>
</div>
<a class="col offset-s1 s3 btn waves-effect white-text thumbnail_input_send">Send</a>
</form>
</div>
<div class="row">
<form id="description_input_form" class="col s12">
<div class="input-field col s8">
<input id="description_input" name="user-pass" type="text" autocomplete="off" />
<label for="description_input" class="noselect">Description</label>
</div>
<a class="col offset-s1 s3 btn waves-effect orange white-text description_input_send">Send</a>
</form>
</div>
<div class="row">
<form id="rules_input_form" class="col s12">
<div class="input-field col s8">
<textarea id="rules_input" class="materialize-textarea"></textarea>
<label for="rules_input">Rules</label>
</div>
<a class="col offset-s1 s3 btn waves-effect green white-text rules_input_send">Send</a>
</form>
</div>
</div>
<div class="modal-footer">
<a href="#!" id="abort-channel-login" class="modal-action modal-close waves-effect waves-green btn-flat close-user-password">Close</a>
</div>
</div>
<div id="user_password" class="modal">
<div class="modal-content">
<h5>Locked Channel</h5>

View File

@@ -3,168 +3,13 @@
<i class="material-icons auto-margin">close</i>
</div>
<ul class="collapsible collapsible-accordion settings-collapsible">
<li class="no-padding">
<div class="col s9 collapsible-header bold waves-effect admin-settings">
Channel Settings
<i class="material-icons">tune</i>
</div>
<div class="collapsible-body">
<ul>
<form action="#" id="adminForm" onsubmit="return false;">
<li class="white-bg">
<div class="input-field field-settings">
<i id="admin-lock" class="material-icons">lock</i>
<input placeholder="Enter admin password" id="password" type="password" class="validate" />
</div>
</li>
<li>
<span class="switch-text">
Add songs
</span>
<div class="switch">
<label>
<span class="left-span">Anyone</span>
<input name="addsongs" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Admin</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Vote
</span>
<div class="switch">
<label>
<span class="left-span">Anyone</span>
<input name="vote" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Admin</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Shuffle
</span>
<div class="switch">
<label>
<span class="left-span">Anyone</span>
<input name="shuffle" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Admin</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Skip
</span>
<div class="switch">
<label>
<span class="left-span">Anyone</span>
<input name="skip" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Admin</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Song length
</span>
<div class="switch">
<label>
<span class="left-span">Any</span>
<input name="longsongs" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Short</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Type
</span>
<div class="switch">
<label>
<span class="left-span">Any</span>
<input name="allvideos" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Song</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Frontpage
</span>
<div class="switch">
<label>
<span class="left-span">Hide</span>
<input name="frontpage" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Display</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
After play
</span>
<div class="switch">
<label>
<span class="left-span">Keep</span>
<input name="removeplay" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Remove</span>
</label>
</div>
</li>
<li class="user-password-li hide">
<span class="switch-text">
Channel password
</span>
<div class="switch">
<label>
<span class="left-span">No</span>
<input name="userpass" type="checkbox" class="conf password_protected" /><span class="lever"></span>
<span class="right-span">Yes</span>
</label>
</div>
</li>
</form>
<li class="change_user_pass hide">
<a href="#!" class="change_user_pass_btn btn waves-effect blue">Change password</a>
</li>
<li class="delete-all hide">
<a href="#" class="delete-all-songs btn red">Delete all songs</a>
</li>
</ul>
</div>
</li>
<li class="no-padding">
{{> channel/settings}}
<li class="no-padding active">
<div class="collapsible-header bold waves-effect">Channel Info
<i class="material-icons">info_outline</i>
</div>
<div class="collapsible-body">
<div class="collapsible-body info_collapsible">
<ul>
<li>
<form id="thumbnail_form" style="display:none;">
<div class="input-field col s12 admin-information">
<input type="text" placeholder="Channel thumbnail" name="chan_thumbnail" id="chan_thumbnail" autocomplete="off" />
</div>
</form>
</li>
<li>
<form id="description_form" style="display:none;">
<div class="input-field col s12 admin-information">
<input type="text" placeholder="Channel description" name="chan_description" id="chan_description" autocomplete="off" maxlength="100" data-length="100" />
</div>
</form>
</li>
<li class="channel_info_container">
<div id="thumbnail_image">
</div>
@@ -172,9 +17,15 @@
This channel doesn't have a description yet.
</div>
</li>
<li class="white-bg info_change_li hide">
<div class="row info_change_button_container">
<a href="#" class="info_change_button col s8 offset-s2 btn orange waves-effect">Change</a>
</div>
</li>
</ul>
</div>
</li>
{{> channel/client_settings}}
{{#unless client}}
<li class="no-padding remote-panel hide-on-small-only">
<div class="collapsible-header bold waves-effect">Remote Control
@@ -183,16 +34,6 @@
<div class="collapsible-body">
<ul>
<li>
<span class="switch-text">
Enable Remote
</span>
<div class="switch">
<label>
Disabled
<input name="remote_switch" type="checkbox" class="remote_switch_class" checked /><span class="lever"></span>
Enabled
</label>
</div>
<div><a id="code-link" target="_blank">
<img id="code-qr" alt="QR code for control" title="Link to control this Zoff player" src="https://chart.googleapis.com/chart?chs=221x221&amp;cht=qr&amp;choe=UTF-8&amp;chld=L%7C1&amp;chl=http://zoff.me" />
@@ -205,30 +46,6 @@
</ul>
</div>
</li>
<li class="no-padding offline-panel">
<div class="collapsible-header bold waves-effect">Local Mode
<i class="material-icons">visibility_off</i>
</div>
<div class="collapsible-body">
<ul>
<li>
<span class="switch-text">
Local Mode
</span>
<div class="switch">
<label>
Disabled
<input name="offline_switch" type="checkbox" class="offline_switch_class" /><span class="lever"></span>
Enabled
</label>
</div>
<div id="offline-info">
By enabling local mode, you won't receive updates in position of the currently playing song, you'll be able to vote as many times as you please, and you can skip to a specific location in the song.
</div>
</li>
</ul>
</div>
</li>
<li class="no-padding host-mode-panel hide-on-small-only">
<div class="collapsible-header bold waves-effect">Host Mode
<i class="material-icons">hearing</i>
@@ -266,7 +83,7 @@
</div>
<div class="collapsible-body">
<ul id="remote-mobile-container">
<li class="white-bg">
<li class="white-bg container">
<p id="remote_header">Control another client</p>
<form action="#" class="row" id="remoteform">
<div class="input-field col s12">
@@ -343,6 +160,26 @@
</form>
</div>
</li>
<li class="white-bg">
<div class="input-field field-settings soundcloud-import-button import-buttons">
<a class="waves-effect btn import-soundcloud" title="Import SoundCloud playlist">
<img src="https://developers.soundcloud.com/assets/logo_big_white-65c2b096da68dd533db18b9f07d14054.png" class="left soundcloud_logo" alt="SoundCloud Logo" />
<span>SoundCloud</span>
</a>
</div>
<div class="input-field field-settings soundcloud_authenticated hide">
<form action="#" id="listImportSoundCloud">
<i class="material-icons import-icon">playlist_add</i>
<input title="Input SoundCloud-playlist url here!" placeholder="Enter SoundCloud-list url" id="import_soundcloud" type="text" class="validate" autocomplete="off" />
<p class="soundcloud-disclaimer">If you want to add a private list, remember to add the secret token at the end!</p>
</form>
<div id="playlist_loader_soundcloud" class="valign playlist_loader_padding hide">
<div class="preloader-wrapper small active">
{{> spinner}}
</div>
</div>
</div>
</li>
<li class="white-bg">
<div class="input-field field-settings import-buttons import-zoff-container">
<a class="waves-effect zoff-color lighten btn import-zoff" title="Import Zoff playlist">
@@ -397,6 +234,14 @@
</a>
</div>
</li>
<li class="white-bg">
<div class="input-field field-settings soundcloud-export-button export-buttons">
<a class="waves-effect btn export-soundcloud" title="Export to SoundCloud">
<img src="https://developers.soundcloud.com/assets/logo_big_white-65c2b096da68dd533db18b9f07d14054.png" class="left soundcloud_logo" alt="SoundCloud Logo" />
<span>SoundCloud</span>
</a>
</div>
</li>
<li class="exported-list-container white-bg hide">
<div class="valign playlist_loader_padding">
<div class="row">

View File

@@ -4,42 +4,42 @@
<div id="fireplace_player" class="ytplayer"></div>
{{/unless}}
<div id="player" class="ytplayer"></div>
<div id="main_components">
<div id="player_overlay" class="hide valign-wrapper">
<div id="playing_on">
<div id="chromecast_icon">
<i class="material-icons">cast</i>
</div>
<div id="chromecast_text"></div>
<div id="sc_player" class="scplayer"></div>
<div id="player_overlay" class="hide valign-wrapper">
<div id="playing_on">
<div id="chromecast_icon">
<i class="material-icons">cast</i>
</div>
<div class="soundcloud_info_container hide">
<a href="#!" id="soundcloud_listen_link" target="_blank">
<img src="https://developers.soundcloud.com/assets/powered_by_large_white-9c2af6a93ad2b1c541f423d9e9045980.png" />
</a>
<a href="#!" class="btn green waves-effect waves-light" target="_blank">Artist</a>
</div>
<div id="player_overlay_text" class="valign center-align">
Waiting for Video
</div>
<div id="player_loader_container" class="hide valign-wrapper">
<div id="player_loader" class="preloader-wrapper large active valign">
{{> spinner}}
</div>
</div>
<div id="player_overlay_controls" class="hide valign-wrapper">
<div id="playpause-overlay" class="valign center-align">
<i id="play-overlay" class="material-icons hide">play_arrow</i>
<i id="pause-overlay" class="material-icons">pause</i>
</div>
<div id="volume-button-overlay">
<i id="v-mute-overlay" class="material-icons">volume_off</i>
<i id="v-low-overlay" class="material-icons">volume_mute</i>
<i id="v-medium-overlay" class="material-icons">volume_down</i>
<i id="v-full-overlay" class="material-icons">volume_up</i>
</div>
<div id="chromecast_text"></div>
</div>
<div class="soundcloud_info_container hide">
<a href="#!" id="soundcloud_listen_link" target="_blank">
<img src="https://developers.soundcloud.com/assets/powered_by_large_white-9c2af6a93ad2b1c541f423d9e9045980.png" />
</a>
<a href="#!" class="btn green waves-effect waves-light" target="_blank">Artist</a>
</div>
<div id="player_overlay_text" class="valign center-align">
Waiting for Video
</div>
<div id="player_loader_container" class="hide valign-wrapper">
<div id="player_loader" class="preloader-wrapper large active valign">
{{> spinner}}
</div>
</div>
<div id="player_overlay_controls" class="hide valign-wrapper">
<div id="playpause-overlay" class="valign center-align">
<i id="play-overlay" class="material-icons hide">play_arrow</i>
<i id="pause-overlay" class="material-icons">pause</i>
</div>
<div id="volume-button-overlay">
<i id="v-mute-overlay" class="material-icons">volume_off</i>
<i id="v-low-overlay" class="material-icons">volume_mute</i>
<i id="v-medium-overlay" class="material-icons">volume_down</i>
<i id="v-full-overlay" class="material-icons">volume_up</i>
</div>
</div>
</div>
<div id="main_components">
<div id="controls" class="noselect">
<div class="playbar-btn prev playbar hide">
<i class="material-icons">skip_previous</i>
@@ -66,7 +66,18 @@
<div id="volume"></div>
</div>
<div id="viewers" data-position="top"></div>
<div id="addToOtherList" class="playbar-btn">
<i class="material-icons">playlist_add</i>
</div>
<div id="bar"></div>
</div>
<div id="addToListInput" class="hide">
<div class="input-field field-settings">
<span>Add to other list</span>
<form action="#" id="addToOtherListForm" onsubmit="return false;">
<input placeholder="List-name" id="other-list-name-add" type="text" autocomplete="off">
</form>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,169 @@
<li class="no-padding">
<div class="col s9 collapsible-header bold waves-effect admin-settings">
Channel Settings
<i class="material-icons">tune</i>
</div>
<div class="collapsible-body">
<ul>
<form action="#" id="adminForm" onsubmit="return false;">
<li class="white-bg">
<div class="input-field field-settings">
<i id="admin-lock" class="material-icons">lock</i>
<input placeholder="Enter admin password" id="password" type="password" class="validate" />
</div>
</li>
</form>
<form action="#" id="adminSettingsForm" onsubmit="return false;">
<li>
<span class="switch-text">
Add songs
</span>
<div class="switch">
<label>
<span class="left-span">Anyone</span>
<input name="addsongs" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Admin</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Vote
</span>
<div class="switch">
<label>
<span class="left-span">Anyone</span>
<input name="vote" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Admin</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Shuffle
</span>
<div class="switch">
<label>
<span class="left-span">Anyone</span>
<input name="shuffle" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Admin</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Skip
</span>
<div class="switch">
<label>
<span class="left-span">Anyone</span>
<input name="skip" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Admin</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Song length
</span>
<div class="switch">
<label>
<span class="left-span">Any</span>
<input name="longsongs" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Short</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Type
</span>
<div class="switch">
<label>
<span class="left-span">Any</span>
<input name="allvideos" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Song</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
Frontpage
</span>
<div class="switch">
<label>
<span class="left-span">Hide</span>
<input name="frontpage" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Display</span>
</label>
</div>
</li>
<li>
<span class="switch-text">
After play
</span>
<div class="switch">
<label>
<span class="left-span">Keep</span>
<input name="removeplay" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Remove</span>
</label>
</div>
</li>
<li class="chat-toggle-li hide">
<span class="switch-text">
Strict skip
</span>
<div class="switch">
<label>
<span class="left-span">Off</span>
<input name="strictSkip" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">On</span>
</label>
</div>
</li>
<li class="chat-toggle-li hide">
<span class="switch-text">
Chat
</span>
<div class="switch">
<label>
<span class="left-span">Disabled</span>
<input name="toggleChat" type="checkbox" class="conf" /><span class="lever"></span>
<span class="right-span">Enabled</span>
</label>
</div>
</li>
<li class="user-password-li hide">
<span class="switch-text">
Password
</span>
<div class="switch">
<label>
<span class="left-span">No</span>
<input name="userpass" type="checkbox" class="conf password_protected" /><span class="lever"></span>
<span class="right-span">Yes</span>
</label>
</div>
</li>
</form>
<form action="#" id="strictSkipForm" onsubmit="return false;">
<li class="white-bg strict-skip-input hide">
<div class="input-field field-settings">
<i id="strict-skip-lock" class="material-icons">queue_play_next</i>
<input placeholder="Strict skip number" id="strict-input-number" type="number" class="validate" />
<div class="strict-skip-info">votes needed to skip.</div>
</div>
</li>
</form>
<li class="change_user_pass hide">
<a href="#!" class="change_user_pass_btn btn waves-effect blue">Change password</a>
</li>
<li class="delete-all hide">
<a href="#" class="delete-all-songs btn red">Delete all songs</a>
</li>
</ul>
</div>
</li>

View File

@@ -4,6 +4,11 @@
<li class="tab col s3"><a class="playlist-tab-links playlist-link active truncate" href="#wrapper">Playlist</a></li>
<li class="tab col s3"><a class="playlist-tab-links suggested-link truncate" href="#suggestions">Suggested<span class="new badge white hide suggested-badge"></span></a></li>
<li class="tab col s3"><a class="playlist-tab-links chat-link truncate" href="#chat-container">Chat<span class="new badge white hide"></span></a></li>
<a href="#" class="playlist-search-button">
<li class="">
<i class="material-icons">search</i>
</li>
</a>
</ul>
{{/unless}}
<div id="find_div" class="hide">
@@ -12,6 +17,7 @@
<div class="num_of_found">
<span id="num_found">0</span>/<span id="of_total_found">0</span>
</div>
<a href="#" id="open_advanced_filter"><i class="material-icons">filter_list</i></a>
<a href="#" id="close_find_form_button"><i class="material-icons">clear</i></a>
</form>
</div>

View File

@@ -1,7 +1,9 @@
<div id="donate" class="modal">
<div class="modal-content">
<h4>Donate</h4>
<p>Want to donate and support our server-bills?</p>
<p>Want to donate and support our server-bills, or get a picture of your choice besides your name in chat?</p>
<p>If you've donated 5$ or more just send us an email after you've donated with your username and a small picture, and we'll set you up!</p>
<p>The picture has to be non-offensive or racist of course, and cannot be the Zoff logo or any copyrighted material.</p>
<p>We take all donations happily, via both PayPal, Ethereum (ETH) and Bitcoin core (BTC).</p>
<br>
<br>

View File

@@ -28,7 +28,7 @@
<br><br>
We will use the money for something awesome, just you wait and see!
<br><br>
We might also add your name somewhere in the code as a sign of gratitude, see if you can find it! (Might take a day or two for us to see the donation and implement it..)
If you send us an email saying you donated, your chat-username and a transaction id, we will fix you a chat logo.
</p>
</div>
<div class="modal-footer">

View File

@@ -1,12 +1,14 @@
<div id="about" class="modal">
<div class="modal-content">
<h4>About</h4>
<p>Zoff (pronounced <b>søff</b>) is a shared (free) YouTube and SoundCloud based radio service, built upon the YouTube and SoundCloud API. <br><br>
Zoff is mainly a web-based service. The website uses NodeJS with Socket.IO, MongoDB and express on the backend, with JavaScript and Materialize on the frontend.<br><br>
The team consists of Kasper Rynning-Tønnesen and Nicolas Almagro Tonne, and the project has been worked on since late 2014.<br><br>
<p>
Zoff (pronounced <b>søff</b>) is a shared (free) YouTube and SoundCloud based radio service, built upon the YouTube and SoundCloud API. It is mainly a web-based service, but there exists a mobile app for voting, adding and skipping in channels. The service is free for all users, with no registration needed.
</p>
<p>
The team consists of Kasper Rynning-Tønnesen and Nicolas Almagro Tonne, and the project has been worked on since late 2014.
</p>
<h4>Legal</h4>
<p>Nicolas Almagro Tonne and Kasper Rynning-Tønnesen<br>&copy; {{year}}
<p>Kasper Rynning-Tønnesen and Nicolas Almagro Tonne<br>&copy; {{year}}
<br><br>
Creative Commons License<br>
Zoff is licensed under a <br><a href="http://creativecommons.org/licenses/by-nc-nd/3.0/no/">Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Norway License.</a>

View File

@@ -1,7 +1,7 @@
<header>
<nav id="fp-nav">
<div class="nav-wrapper">
<a href="https://zoff.me" class="brand-logo brand-logo-navigate hide-on-med-and-down">
<a href="https://zoff.me" class="brand-logo hide-on-med-and-down">
<img class="zicon" src="/assets/images/z.svg" alt="zoff" title="Zoff" />
</a>
<div class="brand-logo truncate zbrand">

View File

@@ -1,301 +1,625 @@
var express = require('express');
var express = require("express");
var router = express.Router();
var path = require('path');
var mongo_db_cred = require(path.join(__dirname, '../../config/mongo_config.js'));
var mongojs = require('mongojs');
var path = require("path");
try {
var mongo_db_cred = require(path.join(
__dirname,
"../../config/mongo_config.js"
));
} catch (e) {
console.log(
"(!) Missing file - /config/mongo_config.js. Have a look at /config/mongo_config.example.js. The server won't run without this existing."
);
process.exit(1);
}
var mongojs = require("mongojs");
var db = mongojs(mongo_db_cred.config);
var token_db = mongojs("tokens");
var uniqid = require('uniqid');
var crypto = require('crypto');
var uniqid = require("uniqid");
var crypto = require("crypto");
var ObjectId = mongojs.ObjectId;
var sIO = require(path.join(__dirname, "../../apps/client.js")).socketIO;
var projects = require(pathThumbnails + "/handlers/aggregates.js");
router.use(function(req, res, next) {
next(); // make sure we go to the next routes and don't stop here
next(); // make sure we go to the next routes and don't stop here
});
router.route('/api/lists').get(function(req, res){
if(req.isAuthenticated()){
db.collection("frontpage_lists").find().sort({count: -1},function(err, docs){
res.json(docs);
router.route("/api/lists").get(function(req, res) {
if (req.isAuthenticated()) {
db.collection("frontpage_lists")
.find()
.sort({ count: -1 }, function(err, docs) {
res.json(docs);
});
} else {
res.send(false);
}
} else {
res.send(false);
}
});
router.route('/api/thumbnails').get(function(req, res){
if(req.isAuthenticated()){
db.collection("suggested_thumbnails").find(function(err, docs){
res.json(docs);
});
} else {
res.send(false);
}
router.route("/api/thumbnails").get(function(req, res) {
if (req.isAuthenticated()) {
db.collection("suggested_thumbnails").find(function(err, docs) {
res.json(docs);
});
} else {
res.send(false);
}
});
router.route('/api/descriptions').get(function(req, res){
if(req.isAuthenticated()){
db.collection("suggested_descriptions").find(function(err, docs){
res.json(docs);
});
} else {
res.send(false);
}
router.route("/api/descriptions").get(function(req, res) {
if (req.isAuthenticated()) {
db.collection("suggested_descriptions").find(function(err, docs) {
res.json(docs);
});
} else {
res.send(false);
}
});
router.route('/api/approve_thumbnail').post(function(req, res){
if(req.isAuthenticated()){
var channel = req.body.channel;
db.collection("suggested_thumbnails").find({channel: channel}, function(err, docs){
var thumbnail = docs[0].thumbnail;
db.collection("frontpage_lists").update({_id: channel}, {$set:{thumbnail: thumbnail}}, {upsert: true}, function(err, docs){
db.collection(channel + "_settings").update({views:{$exists:true}}, {$set:{thumbnail: thumbnail}}, {upsert: true}, function(err, docs){
db.collection("suggested_thumbnails").remove({channel: channel}, function(err, docs){
router.route("/api/rules").get(function(req, res) {
if (req.isAuthenticated()) {
db.collection("suggested_rules").find(function(err, docs) {
res.json(docs);
});
} else {
res.send(false);
}
});
router.route("/api/approve_thumbnail").post(function(req, res) {
if (req.isAuthenticated()) {
var channel = req.body.channel;
db.collection("suggested_thumbnails").find({ channel: channel }, function(
err,
docs
) {
var thumbnail = docs[0].thumbnail;
db.collection("frontpage_lists").update(
{ _id: channel },
{ $set: { thumbnail: thumbnail } },
{ upsert: true },
function(err, docs) {
db.collection(channel + "_settings").update(
{ views: { $exists: true } },
{ $set: { thumbnail: thumbnail } },
{ upsert: true },
function(err, docs) {
db.collection("suggested_thumbnails").remove(
{ channel: channel },
function(err, docs) {
db.collection(channel + "_settings").aggregate(
[
{
$match: {
id: "config"
}
},
{
$project: projects.toShowConfig
}
],
function(err, docs) {
if (docs[0].adminpass !== "") docs[0].adminpass = true;
if (
docs[0].hasOwnProperty("userpass") &&
docs[0].userpass != ""
)
docs[0].userpass = true;
else docs[0].userpass = false;
sIO.to(channel).emit("conf", docs);
res.send(true);
}
);
}
);
}
);
}
);
});
} else {
res.send(false);
}
});
router.route("/api/deny_thumbnail").post(function(req, res) {
if (req.isAuthenticated()) {
var channel = req.body.channel;
db.collection("suggested_thumbnails").remove({ channel: channel }, function(
err,
docs
) {
res.send(true);
});
} else {
res.send(false);
}
});
router.route("/api/approve_rules").post(function(req, res) {
if (req.isAuthenticated()) {
var channel = req.body.channel;
db.collection("suggested_rules").find({ channel: channel }, function(
err,
docs
) {
var rules = docs[0].rules;
db.collection(channel + "_settings").update(
{ views: { $exists: true } },
{ $set: { rules: rules } },
{ upsert: true },
function(err, docs) {
db.collection("suggested_rules").remove(
{ channel: channel },
function(err, docs) {
db.collection(channel + "_settings").aggregate(
[
{
$match: {
id: "config"
}
},
{
$project: projects.toShowConfig
}
],
function(err, docs) {
if (docs[0].adminpass !== "") docs[0].adminpass = true;
if (
docs[0].hasOwnProperty("userpass") &&
docs[0].userpass != ""
)
docs[0].userpass = true;
else docs[0].userpass = false;
sIO.to(channel).emit("conf", docs);
res.send(true);
});
});
});
});
} else {
res.send(false);
}
}
);
}
);
}
);
});
} else {
res.send(false);
}
});
router.route('/api/deny_thumbnail').post(function(req, res){
if(req.isAuthenticated()){
var channel = req.body.channel;
db.collection("suggested_thumbnails").remove({channel: channel},function(err, docs){
res.send(true);
});
} else {
res.send(false);
}
router.route("/api/deny_rules").post(function(req, res) {
if (req.isAuthenticated()) {
var channel = req.body.channel;
db.collection("suggested_rules").remove({ channel: channel }, function(
err,
docs
) {
res.send(true);
});
} else {
res.send(false);
}
});
router.route('/api/approve_description').post(function(req, res){
if(req.isAuthenticated()){
var channel = req.body.channel;
db.collection("suggested_descriptions").find({channel: channel}, function(err, docs){
var description = docs[0].description;
db.collection("frontpage_lists").update({_id: channel}, {$set:{description: description}}, {upsert: true}, function(err, docs){
db.collection(channel + "_settings").update({views:{$exists:true}}, {$set:{description: description}}, function(err, docs){
db.collection("suggested_descriptions").remove({channel: channel}, function(err, docs){
res.send(true);
});
});
});
});
} else {
res.send(false);
}
});
router.route('/api/deny_description').post(function(req, res){
if(req.isAuthenticated()){
var channel = req.body.channel;
db.collection("suggested_descriptions").remove({channel: channel}, 1,function(err, docs){
res.send(true);
});
} else {
res.send(false);
}
});
router.route('/api/remove_thumbnail').post(function(req, res){
if(req.isAuthenticated()){
var channel = req.body.channel;
db.collection("frontpage_lists").update({_id: channel}, {$set:{thumbnail: ""}}, function(err, docs){
db.collection(channel + "_settings").update({views:{$exists:true}}, {$set:{thumbnail: ""}}, function(err, docs){
router.route("/api/remove_rules").post(function(req, res) {
if (req.isAuthenticated()) {
var channel = req.body.channel;
db.collection(channel + "_settings").update(
{ views: { $exists: true } },
{ $set: { rules: "" } },
function(err, docs) {
db.collection(channel + "_settings").aggregate(
[
{
$match: {
id: "config"
}
},
{
$project: projects.toShowConfig
}
],
function(err, docs) {
if (docs[0].adminpass !== "") docs[0].adminpass = true;
if (docs[0].hasOwnProperty("userpass") && docs[0].userpass != "")
docs[0].userpass = true;
else docs[0].userpass = false;
sIO.to(channel).emit("conf", docs);
res.send(true);
});
});
} else {
res.send(false);
}
});
router.route('/api/remove_description').post(function(req, res){
if(req.isAuthenticated()){
var channel = req.body.channel;
db.collection("frontpage_lists").update({_id: channel}, {$set:{description: ""}}, function(err, docs){
db.collection(channel + "_settings").update({views:{$exists:true}}, {$set:{description: ""}}, function(err, docs){
res.send(true);
});
});
} else {
res.send(false);
}
});
router.route('/api/names').get(function(req, res) {
if(req.isAuthenticated()){
db.collection("registered_users").find({_id: {$exists: true}}, {_id: 1, icon: 1}, function(err, docs) {
res.json(docs);
})
} else {
res.send(false);
}
});
router.route('/api/names').post(function(req, res) {
if(req.isAuthenticated()) {
var icon = req.body.icon;
var name = req.body.name;
db.collection("registered_users").update({_id: name}, {$set: {icon: icon}}, function(err, docs) {
if(err) res.send(false);
else res.send(true);
});
} else {
res.send(false);
}
})
router.route('/api/token').get(function(req, res){
if(req.isAuthenticated()){
token_db.collection("tokens").find(function(err, docs){
if(docs.length == 1){
res.json({token: docs[0].token});
} else {
var id = new Buffer(makeid()).toString('base64');
token_db.collection("tokens").insert({token: id}, function(err, docs){
res.json({token: id});
});
}
})
} else {
res.send(false);
}
});
router.route('/api/api_token').get(function(req, res) {
if(req.isAuthenticated()) {
token_db.collection("api_token").find({token: {$exists: true}}, function(err, all) {
res.json(all);
});
} else {
res.sendStatus(403);
}
});
router.route('/api/api_token').delete(function(req, res){
if(req.isAuthenticated()){
var id = req.body.id;
token_db.collection("api_token").remove({_id: ObjectId(id)}, function(err, success) {
if(err) {
res.send("failed");
return;
}
res.send("success");
})
}
});
router.route('/api/api_token').put(function(req, res){
if(req.isAuthenticated()){
var id = req.body.id;
var limit = req.body.limit;
if(limit < 0) {
res.sendStatus(500);
return;
}
);
}
token_db.collection("api_token").update({_id: ObjectId(id)}, {$set: {limit: limit}}, function(err, success) {
if(err) {
res.sendStatus(500);
return;
}
res.sendStatus(200);
})
}
);
} else {
res.send(false);
}
});
router.route('/api/api_token').post(function(req, res){
if(req.isAuthenticated()){
var name = req.body.name;
var id = crypto.createHash('sha256').update(uniqid()).digest('base64');
token_db.collection("api_token").insert({name: name, token: id, usage: 0}, function(err, docs){
token_db.collection("api_token").find({token: id}, function(err, d) {
res.json({token: id, _id: d[0]._id});
});
router.route("/api/approve_description").post(function(req, res) {
if (req.isAuthenticated()) {
var channel = req.body.channel;
db.collection("suggested_descriptions").find({ channel: channel }, function(
err,
docs
) {
var description = docs[0].description;
db.collection("frontpage_lists").update(
{ _id: channel },
{ $set: { description: description } },
{ upsert: true },
function(err, docs) {
db.collection(channel + "_settings").update(
{ views: { $exists: true } },
{ $set: { description: description } },
function(err, docs) {
db.collection("suggested_descriptions").remove(
{ channel: channel },
function(err, docs) {
db.collection(channel + "_settings").aggregate(
[
{
$match: {
id: "config"
}
},
{
$project: projects.toShowConfig
}
],
function(err, docs) {
if (docs[0].adminpass !== "") docs[0].adminpass = true;
if (
docs[0].hasOwnProperty("userpass") &&
docs[0].userpass != ""
)
docs[0].userpass = true;
else docs[0].userpass = false;
sIO.to(channel).emit("conf", docs);
res.send(true);
}
);
}
);
}
);
}
);
});
} else {
res.send(false);
}
});
router.route("/api/deny_description").post(function(req, res) {
if (req.isAuthenticated()) {
var channel = req.body.channel;
db.collection("suggested_descriptions").remove(
{ channel: channel },
1,
function(err, docs) {
res.send(true);
}
);
} else {
res.send(false);
}
});
router.route("/api/remove_thumbnail").post(function(req, res) {
if (req.isAuthenticated()) {
var channel = req.body.channel;
db.collection("frontpage_lists").update(
{ _id: channel },
{ $set: { thumbnail: "" } },
function(err, docs) {
db.collection(channel + "_settings").update(
{ views: { $exists: true } },
{ $set: { thumbnail: "" } },
function(err, docs) {
db.collection(channel + "_settings").aggregate(
[
{
$match: {
id: "config"
}
},
{
$project: projects.toShowConfig
}
],
function(err, docs) {
if (docs[0].adminpass !== "") docs[0].adminpass = true;
if (
docs[0].hasOwnProperty("userpass") &&
docs[0].userpass != ""
)
docs[0].userpass = true;
else docs[0].userpass = false;
sIO.to(channel).emit("conf", docs);
res.send(true);
}
);
}
);
}
);
} else {
res.send(false);
}
});
router.route("/api/remove_description").post(function(req, res) {
if (req.isAuthenticated()) {
var channel = req.body.channel;
db.collection("frontpage_lists").update(
{ _id: channel },
{ $set: { description: "" } },
function(err, docs) {
db.collection(channel + "_settings").update(
{ views: { $exists: true } },
{ $set: { description: "" } },
function(err, docs) {
db.collection(channel + "_settings").aggregate(
[
{
$match: {
id: "config"
}
},
{
$project: projects.toShowConfig
}
],
function(err, docs) {
if (docs[0].adminpass !== "") docs[0].adminpass = true;
if (
docs[0].hasOwnProperty("userpass") &&
docs[0].userpass != ""
)
docs[0].userpass = true;
else docs[0].userpass = false;
sIO.to(channel).emit("conf", docs);
res.send(true);
}
);
}
);
}
);
} else {
res.send(false);
}
});
router.route("/api/names").get(function(req, res) {
if (req.isAuthenticated()) {
db.collection("registered_users").find(
{ _id: { $exists: true } },
{ _id: 1, icon: 1 },
function(err, docs) {
res.json(docs);
}
);
} else {
res.send(false);
}
});
router.route("/api/names").post(function(req, res) {
if (req.isAuthenticated()) {
var icon = req.body.icon;
var name = req.body.name;
db.collection("registered_users").update(
{ _id: name },
{ $set: { icon: icon } },
function(err, docs) {
if (err) res.send(false);
else res.send(true);
}
);
} else {
res.send(false);
}
});
router.route("/api/names").delete(function(req, res) {
if (req.isAuthenticated()) {
var name = req.body.name;
db.collection("registered_users").remove({ _id: name }, function(
err,
docs
) {
if (err) res.send(false);
else res.send(true);
});
} else {
res.send(false);
}
});
router.route("/api/token").get(function(req, res) {
if (req.isAuthenticated()) {
token_db.collection("tokens").find(function(err, docs) {
if (docs.length == 1) {
res.json({ token: docs[0].token });
} else {
var id = new Buffer(makeid()).toString("base64");
token_db
.collection("tokens")
.insert({ token: id }, function(err, docs) {
res.json({ token: id });
});
}
});
} else {
res.send(false);
}
});
router.route("/api/api_token").get(function(req, res) {
if (req.isAuthenticated()) {
token_db
.collection("api_token")
.find({ token: { $exists: true } }, function(err, all) {
res.json(all);
});
} else {
res.send(false);
}
} else {
res.sendStatus(403);
}
});
router.route('/api/delete').post(function(req, res){
if(req.isAuthenticated()){
var list = req.body._id;
db.collection(list).drop(function(err, docs){
db.collection("frontpage_lists").remove({_id: list}, function(err, docs){
res.send(true);
})
router.route("/api/api_token").delete(function(req, res) {
if (req.isAuthenticated()) {
var id = req.body.id;
token_db
.collection("api_token")
.remove({ _id: ObjectId(id) }, function(err, success) {
if (err) {
res.send("failed");
return;
}
res.send("success");
});
} else {
res.send(false);
}
}
});
router.route('/api/remove_token').get(function(req, res){
if(req.isAuthenticated()){
token_db.collection("tokens").find(function(err, docs){
if(docs.length == 1){
token_db.collection("tokens").remove({token: docs[0].token}, function(err, docs){
res.send(true);
})
} else {
res.send(false);
}
})
} else {
res.send(false);
}
router.route("/api/api_token").put(function(req, res) {
if (req.isAuthenticated()) {
var id = req.body.id;
var limit = req.body.limit;
if (limit < 0) {
res.sendStatus(500);
return;
}
token_db
.collection("api_token")
.update({ _id: ObjectId(id) }, { $set: { limit: limit } }, function(
err,
success
) {
if (err) {
res.sendStatus(500);
return;
}
res.sendStatus(200);
});
}
});
router.route('/api/pinned').post(function(req, res){
if(req.isAuthenticated()){
var to_pin = req.body._id;
db.collection("frontpage_lists").update({pinned:1}, {$set:{pinned:0}}, function(err, resp){
db.collection("frontpage_lists").update({_id:to_pin}, {$set:{pinned:1}}, function(err, resp){
res.send(true);
});
router.route("/api/api_token").post(function(req, res) {
if (req.isAuthenticated()) {
var name = req.body.name;
var id = crypto
.createHash("sha256")
.update(uniqid())
.digest("base64");
token_db
.collection("api_token")
.insert({ name: name, token: id, usage: 0 }, function(err, docs) {
token_db.collection("api_token").find({ token: id }, function(err, d) {
res.json({ token: id, _id: d[0]._id });
});
} else {
res.send(false);
}
});
router.route('/api/admin').post(function(req, res){
if(req.isAuthenticated()){
var to_remove = req.body._id;
db.collection(to_remove + "_settings").update({views: {$exists: true}}, {$set:{adminpass: ""}}, function(err, docs){
res.send(true);
});
} else {
res.send(false);
}
} else {
res.send(false);
}
});
router.route('/api/userpass').post(function(req, res){
if(req.isAuthenticated()){
var to_remove = req.body._id;
db.collection(to_remove + "_settings").update({views: {$exists: true}}, {$set:{userpass: ""}}, function(err, docs){
res.send(true);
router.route("/api/delete").post(function(req, res) {
if (req.isAuthenticated()) {
var list = req.body._id;
db.collection(list).drop(function(err, docs) {
db.collection(list + "_settings").drop(function(err, docs) {
db.collection("frontpage_lists").remove({ _id: list }, function(
err,
docs
) {
res.send(true);
});
});
} else {
res.send(false);
}
});
} else {
res.send(false);
}
});
function makeid()
{
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
router.route("/api/remove_token").get(function(req, res) {
if (req.isAuthenticated()) {
token_db.collection("tokens").find(function(err, docs) {
if (docs.length == 1) {
token_db
.collection("tokens")
.remove({ token: docs[0].token }, function(err, docs) {
res.send(true);
});
} else {
res.send(false);
}
});
} else {
res.send(false);
}
});
for( var i=0; i < 20; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
router.route("/api/pinned").post(function(req, res) {
if (req.isAuthenticated()) {
var to_pin = req.body._id;
db.collection("frontpage_lists").update(
{ pinned: 1 },
{ $set: { pinned: 0 } },
function(err, resp) {
db.collection("frontpage_lists").update(
{ _id: to_pin },
{ $set: { pinned: 1 } },
function(err, resp) {
res.send(true);
}
);
}
);
} else {
res.send(false);
}
});
return text;
router.route("/api/admin").post(function(req, res) {
if (req.isAuthenticated()) {
var to_remove = req.body._id;
db.collection(to_remove + "_settings").update(
{ views: { $exists: true } },
{ $set: { adminpass: "" } },
function(err, docs) {
res.send(true);
}
);
} else {
res.send(false);
}
});
router.route("/api/userpass").post(function(req, res) {
if (req.isAuthenticated()) {
var to_remove = req.body._id;
db.collection(to_remove + "_settings").update(
{ views: { $exists: true } },
{ $set: { userpass: "" } },
function(err, docs) {
res.send(true);
}
);
} else {
res.send(false);
}
});
function makeid() {
var text = "";
var possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 20; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
module.exports = router;

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,33 @@
var express = require('express');
const path = require('path');
var express = require("express");
const path = require("path");
var router = express.Router();
router.use(function(req, res, next) {
next(); // make sure we go to the next routes and don't stop here
next(); // make sure we go to the next routes and don't stop here
});
router.route('/favicon.ico').get(function(req, res, next) {
res.sendFile(path.join(pathThumbnails, '/public/assets/images/favicon.ico'));
router.route("/favicon.ico").get(function(req, res, next) {
res.sendFile(path.join(pathThumbnails, "/public/assets/images/favicon.ico"));
});
router.route('/browserconfig.xml').get(function(req, res, next) {
res.sendFile(path.join(pathThumbnails, '/public/assets/images/browserconfig.xml'));
router.route("/browserconfig.xml").get(function(req, res, next) {
res.sendFile(
path.join(pathThumbnails, "/public/assets/images/browserconfig.xml")
);
});
router.route('/apple-touch-icon.png').get(function(req, res, next) {
res.sendFile(path.join(pathThumbnails, '/public/assets/images/apple-touch-icon.png'));
router.route("/apple-touch-icon.png").get(function(req, res, next) {
res.sendFile(
path.join(pathThumbnails, "/public/assets/images/apple-touch-icon.png")
);
});
router.route('/apple-touch-icon-precomposed.png').get(function(req, res, next) {
res.sendFile(path.join(pathThumbnails, '/public/assets/images/apple-touch-icon-precomposed.png'));
router.route("/apple-touch-icon-precomposed.png").get(function(req, res, next) {
res.sendFile(
path.join(
pathThumbnails,
"/public/assets/images/apple-touch-icon-precomposed.png"
)
);
});
module.exports = router;

View File

@@ -1,256 +1,288 @@
var express = require('express');
var express = require("express");
var router = express.Router();
var path = require('path');
var year = new Date().getYear()+1900;
var path = require('path');
var path = require("path");
var year = new Date().getYear() + 1900;
var path = require("path");
var analytics = "xx";
var mongojs = require('mongojs');
var google = {};
var adsense = "xx";
var adds = false;
var mongojs = require("mongojs");
var token_db = mongojs("tokens");
var Functions = require(pathThumbnails + '/handlers/functions.js');
var Frontpage = require(pathThumbnails + '/handlers/frontpage.js');
var Functions = require(pathThumbnails + "/handlers/functions.js");
var Frontpage = require(pathThumbnails + "/handlers/frontpage.js");
var db = require(pathThumbnails + '/handlers/db.js');
//var db = require(pathThumbnails + '/handlers/db.js');
var db = require(pathThumbnails + "/handlers/db.js");
try {
analytics = require(path.join(path.join(__dirname, '../../config/'), 'analytics.js'));
} catch(e) {
console.log("No analytics-id found");
google = require(path.join(
path.join(__dirname, "../../config/"),
"google.js"
));
analytics = google.analytics;
adsense = google.adsense;
} catch (e) {
console.log(
"(!) Missing file - /config/google.js Have a look at /config/google.example.js. This is for google analytics."
);
}
try {
var Recaptcha = require('express-recaptcha');
var recaptcha_config = require(path.join(path.join(__dirname, '../../config/'), 'recaptcha.js'));
var RECAPTCHA_SITE_KEY = recaptcha_config.site;
var RECAPTCHA_SECRET_KEY = recaptcha_config.key;
var recaptcha = new Recaptcha(RECAPTCHA_SITE_KEY, RECAPTCHA_SECRET_KEY);
} catch(e) {
console.log("Error - missing file");
console.log("Seems you forgot to create the file recaptcha.js in /server/config/. Have a look at recaptcha.example.js.");
var recaptcha = {
middleware: {
render: (req, res, next) => {
res.recaptcha = ""
next()
}
}
var Recaptcha = require("express-recaptcha");
var recaptcha_config = require(path.join(
path.join(__dirname, "../../config/"),
"recaptcha.js"
));
var RECAPTCHA_SITE_KEY = recaptcha_config.site;
var RECAPTCHA_SECRET_KEY = recaptcha_config.key;
var recaptcha = new Recaptcha(RECAPTCHA_SITE_KEY, RECAPTCHA_SECRET_KEY);
} catch (e) {
console.log(
"(!) Missing file - /config/recaptcha.js Have a look at /config/recaptcha.example.js."
);
var recaptcha = {
middleware: {
render: (req, res, next) => {
res.recaptcha = "";
next();
}
}
};
}
router.use(recaptcha.middleware.render, function(req, res, next) {
next(); // make sure we go to the next routes and don't stop here
next(); // make sure we go to the next routes and don't stop here
});
router.route('/:channel_name').get(function(req, res, next){
channel(req, res, next);
router.route("/:channel_name").get(function(req, res, next) {
channel(req, res, next);
});
router.route('/r/:base64data').get(function(req, res, next){
var channelToRedirect = Buffer.from(req.params.base64data, 'base64');
res.redirect('/' + channelToRedirect);
router.route("/r/:base64data").get(function(req, res, next) {
var channelToRedirect = Buffer.from(req.params.base64data, "base64");
res.redirect("/" + channelToRedirect);
});
router.route('/').get(function(req, res, next){
root(req, res, next);
router.route("/").get(function(req, res, next) {
root(req, res, next);
});
router.route('/').post(function(req, res, next){
root(req, res, next);
router.route("/").post(function(req, res, next) {
root(req, res, next);
});
router.route('/api/apply').get(function(req, res, next) {
var data = {
year: year,
javascript_file: "token.min.js",
captcha: res.recaptcha,
analytics: analytics,
activated: false,
id: "",
correct: false,
stylesheet: "style.css",
embed: false,
og_image: "https://zoff.me/assets/images/small-square.jpg",
}
res.render('layouts/client/token', data);
router.route("/api/embed").get(function(req, res, next) {
var data = {
year: year,
type: "video",
javascript_file: "embed.min.js",
captcha: res.recaptcha,
analytics: analytics,
stylesheet: "embed.css",
embed: true,
og_image: "https://zoff.me/assets/images/small-square.jpg"
};
res.render("layouts/client/embed", data);
});
router.route('/api/apply/:id').get(function(req, res) {
var id = req.params.id;
token_db.collection('api_links').find({id: id}, function(err, result) {
if(result.length == 1) {
token_db.collection('api_links').remove({id: id}, function(e,d) {
token_db.collection('api_token').update({token: result[0].token}, {$set: {active: true}}, function(e,d) {
var data = {
year: year,
javascript_file: "token.min.js",
captcha: res.recaptcha,
analytics: analytics,
activated: true,
token: result[0].token,
correct: true,
stylesheet: "style.css",
embed: false,
og_image: "https://zoff.me/assets/images/small-square.jpg",
}
res.render('layouts/client/token', data);
});
});
} else {
var data = {
router.route("/api/oauth").get(function(req, res, next) {
res.sendFile(path.join(pathThumbnails, "/public/assets/html/callback.html"));
});
router.route("/api/apply").get(function(req, res, next) {
var data = {
year: year,
javascript_file: "token.min.js",
captcha: res.recaptcha,
analytics: analytics,
adsense: adsense,
adds: adds,
type: "website",
activated: false,
id: "",
correct: false,
stylesheet: "style.css",
embed: false,
og_image: "https://zoff.me/assets/images/small-square.jpg"
};
res.render("layouts/client/token", data);
});
router.route("/api/apply/:id").get(function(req, res) {
var id = req.params.id;
token_db.collection("api_links").find({ id: id }, function(err, result) {
if (result.length == 1) {
token_db.collection("api_links").remove({ id: id }, function(e, d) {
token_db
.collection("api_token")
.update(
{ token: result[0].token },
{ $set: { active: true } },
function(e, d) {
var data = {
year: year,
javascript_file: "token.min.js",
captcha: res.recaptcha,
analytics: analytics,
activated: false,
token:"",
correct: false,
adsense: adsense,
adds: adds,
activated: true,
type: "website",
token: result[0].token,
correct: true,
stylesheet: "style.css",
embed: false,
og_image: "https://zoff.me/assets/images/small-square.jpg",
og_image: "https://zoff.me/assets/images/small-square.jpg"
};
res.render("layouts/client/token", data);
}
res.render('layouts/client/token', data);
}
});
);
});
} else {
var data = {
year: year,
javascript_file: "token.min.js",
captcha: res.recaptcha,
analytics: analytics,
adsense: adsense,
adds: adds,
activated: false,
token: "",
type: "website",
correct: false,
stylesheet: "style.css",
embed: false,
og_image: "https://zoff.me/assets/images/small-square.jpg"
};
res.render("layouts/client/token", data);
}
});
});
function root(req, res, next) {
try{
var url = req.headers['x-forwarded-host'] ? req.headers['x-forwarded-host'] : req.headers.host.split(":")[0];
var subdomain = req.headers['x-forwarded-host'] ? req.headers['x-forwarded-host'].split(".") : req.headers.host.split(":")[0].split(".");
/*if(url != "zoff.me" && url != "admin.localhost" && url != "admin.zoff.me" && url != "remote.zoff.me" && url != "fb.zoff.me" && url != "remote.localhost" && url != "localhost") {
res.redirect("https://zoff.me");
return;
}*/
if(subdomain[0] == "remote") {
var data = {
year: year,
javascript_file: "remote.min.js",
captcha: res.recaptcha,
analytics: analytics,
stylesheet: "style.css",
embed: false,
client: false,
og_image: "https://zoff.me/assets/images/small-square.jpg",
}
res.render('layouts/client/remote', data);
} else if(subdomain[0] == "www") {
res.redirect("https://zoff.me");
} else {
var data = {
year: year,
javascript_file: "main.min.js",
captcha: res.recaptcha,
analytics: analytics,
stylesheet: "style.css",
embed: false,
client: false,
og_image: "https://zoff.me/assets/images/small-square.jpg",
channels: [],
}
if(subdomain[0] == "client") {
data.client = true;
}
Frontpage.get_frontpage_lists(function(err, docs){
db.collection("connected_users").find({"_id": "total_users"}, function(err, tot) {
if(docs.length > 0) {
data.channels_exist = true;
data.channels = docs.slice(0, 12);
data.channel_list = JSON.stringify(docs);
} else {
data.channels_exist = false;
data.channels = [];
data.channel_list = [];
}
data.viewers = tot[0].total_users.length;
res.render('layouts/client/frontpage', data);
});
});
}
} catch(e) {
console.log(e);
//res.redirect("https://zoff.me");
try {
var url = req.headers["x-forwarded-host"]
? req.headers["x-forwarded-host"]
: req.headers.host.split(":")[0];
var subdomain = req.headers["x-forwarded-host"]
? req.headers["x-forwarded-host"].split(".")
: req.headers.host.split(":")[0].split(".");
if (subdomain[0] == "remote") {
var data = {
year: year,
javascript_file: "remote.min.js",
captcha: res.recaptcha,
adsense: adsense,
adds: adds,
analytics: analytics,
type: "website",
stylesheet: "style.css",
embed: false,
client: false,
og_image: "https://zoff.me/assets/images/small-square.jpg"
};
res.render("layouts/client/remote", data);
} else if (subdomain[0] == "www") {
res.redirect("https://zoff.me");
} else {
var data = {
year: year,
javascript_file: "main.min.js",
captcha: res.recaptcha,
adsense: adsense,
adds: adds,
analytics: analytics,
stylesheet: "style.css",
type: "website",
embed: false,
client: false,
og_image: "https://zoff.me/assets/images/small-square.jpg",
channels: []
};
if (subdomain[0] == "client") {
data.client = true;
}
Frontpage.get_frontpage_lists(function(err, docs) {
db.collection("connected_users").find({ _id: "total_users" }, function(
err,
tot
) {
if (docs.length > 0) {
data.channels_exist = true;
data.channels = docs.slice(0, 12);
data.channel_list = JSON.stringify(docs);
} else {
data.channels_exist = false;
data.channels = [];
data.channel_list = [];
}
data.viewers = tot[0].total_users.length;
res.render("layouts/client/frontpage", data);
});
});
}
} catch (e) {
console.log(e);
}
}
function channel(req, res, next) {
try{
var url = req.headers['x-forwarded-host'] ? req.headers['x-forwarded-host'] : req.headers.host.split(":")[0];
var subdomain = req.headers['x-forwarded-host'] ? req.headers['x-forwarded-host'].split(".") : req.headers.host.split(":")[0].split(".");
/*if(url != "zoff.me" && url != "admin.localhost" && url != "admin.zoff.me" && url != "remote.zoff.me" && url != "fb.zoff.me" && url != "remote.localhost" && url != "localhost") {
res.redirect("https://zoff.me");
return;
}*/
if(subdomain[0] == "remote") {
var data = {
year: year,
javascript_file: "remote.min.js",
captcha: res.recaptcha,
analytics: analytics,
stylesheet: "style.css",
embed: false,
client: false,
og_image: "https://zoff.me/assets/images/small-square.jpg",
}
res.render('layouts/client/remote', data);
} else if(subdomain.length >= 2 && subdomain[0] == "www") {
res.redirect("https://zoff.me");
} else {
if(req.params.channel_name == "_embed") {
//res.sendFile(path.join(pathThumbnails, '/public/assets/html/embed.html'));
var data = {
year: year,
javascript_file: "embed.min.js",
captcha: res.recaptcha,
analytics: analytics,
stylesheet: "embed.css",
embed: true,
og_image: "https://zoff.me/assets/images/small-square.jpg",
}
res.render('layouts/client/embed', data);
} else if(req.params.channel_name == "o_callback") {
res.sendFile(path.join(pathThumbnails, '/public/assets/html/callback.html'));
} else {
/*db.collection("frontpage_lists").find({"_id": Functions.encodeChannelName(req.params.channel_name)}, function(err, docs) {
console.log(docs);
var og_image = "https://zoff.me/assets/images/small-square.jpg";
if(docs.length == 1) {
if(docs[0].hasOwnProperty("thumbnail")) {
if(docs[0].thumbnail.indexOf("mqdefault.jpg") > -1) docs[0].thumbnail = docs[0].thumbnail.replace("mqdefault", "hqdefault");
og_image = docs[0].thumbnail;
} else {
og_image = "https://img.youtube.com/vi/" + docs[0].id + "/hqdefault.jpg";
}
}*/
var data = {
title: "404: File Not Found",
list_name: capitalizeFirstLetter(Functions.decodeChannelName(req.params.channel_name)),
year: year,
javascript_file: "main.min.js",
captcha: res.recaptcha,
analytics: analytics,
stylesheet: "style.css",
embed: false,
client:false,
og_image: "https://zoff.me/assets/images/small-square.jpg"
}
if(subdomain[0] == "client") {
data.client = true;
}
if(req.params.channel_name == "404") {
res.status(404);
}
res.render('layouts/client/channel', data);
//});
}
}
} catch(e) {
try {
var url = req.headers["x-forwarded-host"]
? req.headers["x-forwarded-host"]
: req.headers.host.split(":")[0];
var subdomain = req.headers["x-forwarded-host"]
? req.headers["x-forwarded-host"].split(".")
: req.headers.host.split(":")[0].split(".");
if (subdomain[0] == "remote") {
var data = {
year: year,
javascript_file: "remote.min.js",
captcha: res.recaptcha,
adsense: adsense,
adds: adds,
analytics: analytics,
type: "website",
stylesheet: "style.css",
embed: false,
client: false,
og_image: "https://zoff.me/assets/images/small-square.jpg"
};
res.render("layouts/client/remote", data);
} else if (subdomain.length >= 2 && subdomain[0] == "www") {
res.redirect("https://zoff.me");
} else {
if (req.params.channel_name == "o_callback") {
res.redirect("/api/oauth");
} else {
var data = {
title: "404: File Not Found",
list_name: capitalizeFirstLetter(req.params.channel_name),
year: year,
javascript_file: "main.min.js",
captcha: res.recaptcha,
adsense: adsense,
adds: adds,
analytics: analytics,
type: "video",
stylesheet: "style.css",
embed: false,
client: false,
og_image: "https://zoff.me/assets/images/small-square.jpg"
};
if (subdomain[0] == "client") {
data.client = true;
}
res.render("layouts/client/channel", data);
}
}
} catch (e) {
res.redirect("https://zoff.me");
}
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
return string.charAt(0).toUpperCase() + string.slice(1);
}
module.exports = router;