communityStation.html 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. <template name="communityStation">
  2. <header>
  3. <nav>
  4. <div class="nav-wrapper light-blue accent-4">
  5. <ul class="left hide-on-med-and-down">
  6. <li><a style="margin-left: 0px; padding-left: 20px; padding-right: 20px;" href="/"
  7. class="brand-logo">Musare</a></li>
  8. <!--li><a id="vote-skip" class="tooltipped" data-position="bottom" data-delay="50" data-tooltip="Vote to skip this song"><i class="material-icons left">skip_next</i>{{votes}}</a></li-->
  9. {{#if isCommunityStationOwner name}}
  10. <li style="margin-left: 144px;" class={{pausedHidden}}><a id="pause" data-position="bottom" data-delay="50" data-tooltip="Pause this room" data-activates="chat-slide-out" class="tooltipped"><i class="material-icons">pause</i></a></li>
  11. <li style="margin-left: 144px;" class={{playingHidden}}><a id="play" data-position="bottom" data-delay="50" data-tooltip="Play this room" data-activates="chat-slide-out" class="tooltipped"><i class="material-icons">play_arrow</i></a></li>
  12. <li><a id="skip" data-position="bottom" data-delay="50" data-tooltip="Skip this song"
  13. data-activates="chat-slide-out" class="tooltipped"><i
  14. class="material-icons">skip_next</i></a></li>
  15. <li><a id="edit_room" href="#edit_room_modal" data-position="bottom" data-delay="50"
  16. data-tooltip="Edit this room" data-activates="chat-slide-out" class="tooltipped"><i
  17. class="material-icons">settings</i></a></li>
  18. {{/if}}
  19. </ul>
  20. <span class="brand-logo center">{{communityStationDisplayName}}
  21. <small>(by {{communityStationOwnerName}})</small></span>
  22. <ul class="right hide-on-med-and-down">
  23. <li class="{{partyModeEnabledHidden}}"><a href="#" data-position="bottom" data-delay="50" data-tooltip="Queue" id="playlist-slideout" data-activates="queue-slide-out" class="tooltipped header-collapse"><i class="material-icons">queue_music</i></a></li>
  24. {{#if isLoggedIn}}
  25. <li><a href="#" data-position="bottom" data-delay="50" data-tooltip="Chat" id="chat-slideout"
  26. data-activates="chat-slide-out" class="tooltipped header-collapse"><i
  27. class="material-icons">chat</i></a></li>
  28. {{/if}}
  29. {{#if isCommunityStationOwner name}}
  30. <li><a href="#" data-position="bottom" data-delay="50" data-tooltip="Users" id="users-slideout"
  31. data-activates="users-slide-out" class="tooltipped header-collapse"><i
  32. class="material-icons">people</i></a></li>
  33. <li><a href="#" data-position="bottom" data-delay="50" data-tooltip="Allowed"
  34. id="allowed-slideout" data-activates="allowed-slide-out"
  35. class="tooltipped header-collapse"><i class="material-icons">assignment</i></a></li>
  36. <li><a href="#" data-position="bottom" data-delay="50" data-tooltip="Playlists"
  37. id="playlists-slideout" data-activates="playlists-slide-out"
  38. class="tooltipped header-collapse"><i class="material-icons">library_music</i></a></li>
  39. {{/if}}
  40. </ul>
  41. </div>
  42. </nav>
  43. </header>
  44. {{> alerts}}
  45. <main id="room-content">
  46. <div class="container room-container">
  47. {{#if noCurrentSong}}
  48. <h1 class="center musare-text">There's currently no song playing.</h1>
  49. {{/if}}
  50. <div class="row {{noCurrentSongHidden}}">
  51. <div class="col s12 m10 l8 offset-l2 offset-m1" id="media-container">
  52. <div class="video-container">
  53. <div id="player"></div>
  54. </div>
  55. </div>
  56. <div class="col s12 m10 l8 offset-l2 offset-m1">
  57. <h4 id="time-display"><span id="time-elapsed"></span> / <span id="time-total"></span></h4>
  58. <h3>{{{title}}}</h3>
  59. <div class="row">
  60. <form action="#" class="left col s4 m4 l4">
  61. <p class="range-field" style="margin-top: 0">
  62. <input type="range" id="volume_slider" min="0" max="100"/>
  63. </p>
  64. </form>
  65. </div>
  66. <div class="seeker-bar-container white" id="preview-progress">
  67. <div class="seeker-bar light-blue" style="width: 0%"></div>
  68. </div>
  69. </div>
  70. </div>
  71. </div>
  72. </main>
  73. <!--Chat slideout-->
  74. <div id="chat-slide-out" class="side-nav room-slideout">
  75. <h5>Chat</h5>
  76. <ul class="chat-ul">
  77. {{#each globalChat}}
  78. {{#emojione}}
  79. <li class="chat-message" style="line-height: 30px">
  80. <span title="{{time}}" style="float: right; margin-top: 15px">{{rtime time}}</span>
  81. <a style="text-decoration: none; font-size: 0.9em; height: 0.9em; font-weight: 500"
  82. href="/u/{{this.username}}" target="_blank"><span
  83. class="rank-{{this.rawrank}}">{{this.rank}}</span>{{this.username}}</a>
  84. <p style="clear: both; line-height: 1.2em; margin-left: 13px; margin-bottom: 0; font-size: 1.2em">{{{this.message}}}</p>
  85. </li>
  86. {{/emojione}}
  87. <div class="divider" style="margin-top: 15px;"></div>
  88. {{/each}}
  89. </ul>
  90. <div>
  91. <div class="row" id="chat-input-div">
  92. <div class="input-field col s12">
  93. {{#if currentUser}}
  94. <input id="chat-message" type="text">
  95. <label for="chat-message">Send a message</label>
  96. {{else}}
  97. <input id="chat-message" class="disabled" disabled type="text">
  98. <label for="chat-message">You have to be logged in to chat.</label>
  99. {{/if}}
  100. </div>
  101. </div>
  102. {{#if currentUser}}
  103. <a id="submit" class="waves-effect waves-light btn">Send</a>
  104. {{else}}
  105. <a id="submit" class="waves-effect waves-light btn disabled" disabled>Send</a>
  106. {{/if}}
  107. </div>
  108. </div>
  109. <!--Playlist slideout-->
  110. <div id="queue-slide-out" class="side-nav room-slideout">
  111. <h5>Queue</h5>
  112. <ul id="queue-ul" style="max-height: calc(100% - 105px); overflow-y: auto; margin: 0;">
  113. {{#each song in queue}}
  114. <li class="queue-item" style="clear: both">
  115. <a class="queue-item-remove" style="float:right; height: 0; width: 0;" href="#" data-id={{song.song.id}}><i class="material-icons" data-id={{song.song.id}}>clear</i></a>
  116. <div class="queue-item-text">
  117. <p class="queue-item-title">{{song.song.title}}</p>
  118. <p class="queue-item-username">Added by <a style="display: inline-block; height: 10px; padding: 0; color: #039be5;" href="/profile/{{getUsernameFromId song.requestedBy}}">{{getUsernameFromId song.requestedBy}}</a></p>
  119. </div>
  120. <hr>
  121. </li>
  122. {{/each}}
  123. </ul>
  124. <a id="add-song-to-queue-button" class="waves-effect waves-light btn musare white-text" href="#add-song-to-queue">Add song to queue</a>
  125. </div>
  126. <div id="users-slide-out" class="side-nav room-slideout">
  127. <h5>Users In Room</h5>
  128. <ul style="margin-bottom: 64px;">
  129. {{#each usersInRoom}}
  130. <li><a href=/u/{{this}} target="_blank">{{this}}</a></li>
  131. {{/each}}
  132. </ul>
  133. {{#if currentUser}}
  134. <a class="btn btn-block musare white-text waves-effect waves-light" href="#" id="logout"
  135. style="position: fixed; bottom: 0; width: 342px;">Logout</a>
  136. {{else}}
  137. <a class="btn btn-block musare white-text waves-effect waves-light" href="/login"
  138. style="position: fixed; bottom: 0; width: 342px;">Login / Register</a>
  139. {{/if}}
  140. </div>
  141. <div id="allowed-slide-out" class="side-nav room-slideout">
  142. <h5>Allowed</h5>
  143. <ul class="list-ul" id="allowed-ul">
  144. {{#each allowed}}
  145. <li>
  146. <a href=/u/{{this.name}} target="_blank">
  147. {{this.name}}
  148. {{#if isCommunityStationOwner name}}
  149. <a href="#" class="right remove-allowed" data-user={{this.id}}>
  150. <i class="material-icons" style="line-height: 64px;">remove</i>
  151. </a>
  152. {{/if}}
  153. </a>
  154. </li>
  155. {{/each}}
  156. </ul>
  157. {{#if isCommunityStationOwner name}}
  158. <div>
  159. <div class="row" id="chat-input-div">
  160. <div class="input-field col s12">
  161. <input id="add-allowed" type="text">
  162. <label for="add-allowed">Add user</label>
  163. </div>
  164. </div>
  165. <a id="add-allowed-submit" class="waves-effect waves-light btn">Add</a>
  166. </div>
  167. {{/if}}
  168. </div>
  169. <div id="playlists-slide-out" class="side-nav room-slideout">
  170. <h5>Playlists</h5>
  171. <ul class="list-ul" id="playlists-ul">
  172. {{#each playlists}}
  173. <li>
  174. <a href="#edit_playlist_modal" class="edit-playlist-button" data-playlist={{this.name}}>
  175. {{this.displayName}}
  176. <a href="#" class="right select-playlist" data-playlist={{this.name}}>
  177. {{#if isCommunityStationOwner name}}
  178. {{#if isPlaylistSelected name this.name}}
  179. <i class="material-icons" style="line-height: 64px;">check_circle</i>
  180. {{else}}
  181. <i class="material-icons" data-playlist={{this.name}} style="line-height: 64px;"
  182. title="Select playlist">panorama_fish_eye</i>
  183. {{/if}}
  184. {{/if}}
  185. </a>
  186. </a>
  187. </li>
  188. {{/each}}
  189. </ul>
  190. <div>
  191. <a id="add-playlist-modal-button" class="waves-effect waves-light btn" href="#create_playlist_modal">Create
  192. Playlist</a>
  193. </div>
  194. </div>
  195. <!-- Edit Room Modal -->
  196. <div id="edit_room_modal" class="modal">
  197. <div class="modal-content">
  198. <h4>Edit Room</h4>
  199. <div class="input-field">
  200. <input id="edit_room_description" value={{room.roomDesc}} type="text">
  201. <label for="edit_room_description">Description</label>
  202. </div>
  203. <div class="input-field">
  204. <input id="edit_room_display" value={{room.displayName}} type="text">
  205. <label for="edit_room_display">Display Name</label>
  206. </div>
  207. <div class="input-field col s12">
  208. <select id="edit_room_privacy">
  209. <option value="public" {{getSelected 'public' room.privacy}}>Public</option>
  210. <option value="unlisted" {{getSelected 'unlisted' room.privacy}}>Unlisted</option>
  211. <option value="community" {{getSelected 'community' room.privacy}}>Private</option>
  212. </select>
  213. <label>Room Privacy</label>
  214. </div>
  215. <p>
  216. <input type="checkbox" id="partyModeEnabled" {{partyModeChecked}} />
  217. <label for="partyModeEnabled">Party Mode Enabled</label>
  218. <br><small><b>What is party mode?</b> Party mode is a mode in community stations where, if enabled, people can request songs to be added to the queue, which will then be played in the station.</small>
  219. </p>
  220. {{#if partyModeEnabled}}
  221. <p>
  222. <input type="checkbox" id="queueLocked" {{queueLockedChecked}} />
  223. <label for="queueLocked">Queue Locked</label>
  224. <br><small>Locking the queue will disallow normal users from adding songs to the queue.</small>
  225. </p>
  226. {{/if}}
  227. <button class="btn waves-effect waves-light" id="save_edit_room_changes">Save Changes</button>
  228. <button class="btn waves-effect waves-light right red" id="delete_room">Delete Room</button>
  229. </div>
  230. <div class="divider"></div>
  231. <div class="modal-footer">
  232. <a class="modal-action modal-close waves-effect btn">Close</a>
  233. </div>
  234. </div>
  235. <!-- Edit Playlist Modal -->
  236. <div id="edit_playlist_modal" class="modal">
  237. <div class="modal-content">
  238. <h4>Editing: {{editingPlaylist.name}}</h4>
  239. <ul class="collection">
  240. {{#each song in editingPlaylist.songs}}
  241. <li class="collection-item">
  242. <a href="https://youtube.com/watch?v={{song.id}}" target="_blank">{{song.title}}</a>
  243. <a href="#" class="secondary-content playlistSongRemove" data-id={{song.id}}><i
  244. class="material-icons" data-id={{song.id}}>delete</i></a>
  245. {{#if hasMoreThanOne editingPlaylist.songs}}
  246. {{#if isFirst song editingPlaylist.songs}}
  247. <a href="#" class="secondary-content playlistSongDown" data-id={{song.id}}><i
  248. class="material-icons" data-id={{song.id}}>keyboard_arrow_down</i></a>
  249. {{else}}
  250. {{#if isLast song editingPlaylist.songs}}
  251. <a href="#" class="secondary-content playlistSongUp" data-id={{song.id}}><i
  252. class="material-icons" data-id={{song.id}}>keyboard_arrow_up</i></a>
  253. {{else}}
  254. <a href="#" class="secondary-content playlistSongDown" data-id={{song.id}}><i
  255. class="material-icons" data-id={{song.id}}>keyboard_arrow_down</i></a>
  256. <a href="#" class="secondary-content playlistSongUp" data-id={{song.id}}><i
  257. class="material-icons" data-id={{song.id}}>keyboard_arrow_up</i></a>
  258. {{/if}}
  259. {{/if}}
  260. {{/if}}
  261. </li>
  262. {{/each}}
  263. </ul>
  264. <div class="input-field">
  265. <input id="song-input" type="text" class="validate">
  266. <label for="search_for_song">Search for song to add</label>
  267. </div>
  268. <a class="waves-effect waves-light btn" id="search-song"><i class="material-icons left">search</i>Search</a>
  269. {{#if singleVideoResultsActive}}
  270. <div id="single-video-results">
  271. <div style="overflow: auto; height: 400px; margin-top: 1rem;">
  272. <ul class="collection light-blue-text">
  273. {{#each result in singleVideoResults}}
  274. <li class="collection-item avatar youtube-search-result-li">
  275. <img src="{{result.image}}" onerror="this.src='/notes.png'" alt=""
  276. class="video-import-thumbnail">
  277. <span class="title video-import-text">{{result.title}}</span>
  278. <p class="video-import-text">{{result.artist}} <br>
  279. <a href="https://youtube.com/watch?v={{result.id}}" target="_blank">View Video
  280. In YouTube</a>
  281. </p>
  282. <a href="#" class="secondary-content addSong" data-result="{{result.id}}"><i
  283. class="material-icons" data-result="{{result.id}}">add</i></a>
  284. </li>
  285. {{/each}}
  286. </ul>
  287. </div>
  288. </div>
  289. {{/if}}
  290. <br>
  291. <div class="input-field">
  292. <input id="rename-playlist-name" type="text" class="validate" value={{editingPlaylist.name}}>
  293. <label for="rename-playlist-name">Rename playlist name</label>
  294. </div>
  295. <div class="input-field">
  296. <input id="rename-playlist-display-name" type="text" class="validate"
  297. value={{editingPlaylist.displayName}}>
  298. <label for="rename-playlist-display-name">Rename playlist display name</label>
  299. </div>
  300. <button class="btn waves-effect waves-light musare" id="rename-playlist-button">Rename playlist</button>
  301. </div>
  302. <div class="divider"></div>
  303. <div class="modal-footer">
  304. <a class="modal-action modal-close waves-effect btn">Close</a>
  305. <button class="btn waves-effect waves-light left red" id="delete_playlist">Delete playlist</button>
  306. </div>
  307. </div>
  308. <!-- Edit Playlist Modal -->
  309. <div id="add-song-to-queue" class="modal">
  310. <div class="modal-content">
  311. <h4>Add song to queue</h4>
  312. <div class="input-field">
  313. <input id="add-song-to-queue-search" type="text" class="validate">
  314. <label for="add-song-to-queue-search">Search for song to add</label>
  315. </div>
  316. <a class="waves-effect waves-light btn" id="add-song-to-queue-search-button"><i class="material-icons left">search</i>Search</a>
  317. <a class="waves-effect waves-light btn orange" id="clear-queue-search"><i class="material-icons left">delete</i>Clear results</a>
  318. </div>
  319. {{#if singleVideoResultsActiveQueue}}
  320. <div id="single-video-results-queue">
  321. <div style="overflow: auto; height: 400px; margin-top: 1rem;">
  322. <ul class="collection light-blue-text">
  323. {{#each result in singleVideoResultsQueue}}
  324. <li class="collection-item avatar youtube-search-result-li">
  325. <img src="{{result.image}}" onerror="this.src='/notes.png'" alt=""
  326. class="video-import-thumbnail">
  327. <span class="title video-import-text">{{result.title}}</span>
  328. <p class="video-import-text">{{result.artist}} <br>
  329. <a href="https://youtube.com/watch?v={{result.id}}" target="_blank">View Video
  330. In YouTube</a>
  331. </p>
  332. <a href="#" class="secondary-content addSongQueue" data-result="{{result.id}}"><i
  333. class="material-icons" data-result="{{result.id}}">add</i></a>
  334. </li>
  335. {{/each}}
  336. </ul>
  337. </div>
  338. </div>
  339. {{/if}}
  340. <div class="divider"></div>
  341. <div class="modal-footer">
  342. <a class="modal-action modal-close waves-effect btn">Close</a>
  343. </div>
  344. </div>
  345. <!-- Create Playlist Modal -->
  346. <div id="create_playlist_modal" class="modal">
  347. <div class="modal-content">
  348. <h4>Create Modal</h4>
  349. <div class="input-field">
  350. <input id="create_playlist_name" type="text">
  351. <label for="create_playlist_name">Name</label>
  352. </div>
  353. <div class="input-field">
  354. <input id="create_playlist_display_name" type="text">
  355. <label for="create_playlist_display_name">Display Name</label>
  356. </div>
  357. <button class="btn waves-effect waves-light" id="create_playlist_submit">Create</button>
  358. </div>
  359. <div class="divider"></div>
  360. <div class="modal-footer">
  361. <a class="modal-action modal-close waves-effect btn">Close</a>
  362. </div>
  363. </div>
  364. <script>
  365. $("#add-song-to-queue-button").leanModal({
  366. dismissible: true,
  367. opacity: .5,
  368. in_duration: 500,
  369. out_duration: 200
  370. });
  371. $(".edit-playlist-button").leanModal({
  372. dismissible: true,
  373. opacity: .5,
  374. in_duration: 500,
  375. out_duration: 200
  376. });
  377. $("#add-playlist-modal-button").leanModal({
  378. dismissible: true,
  379. opacity: .5,
  380. in_duration: 500,
  381. out_duration: 200
  382. });
  383. $("#edit_room").leanModal({
  384. dismissible: true,
  385. opacity: .5,
  386. in_duration: 500,
  387. out_duration: 200
  388. });
  389. $(".dropdown-button").dropdown({
  390. belowOrigin: true
  391. });
  392. $('select').material_select();
  393. $("#chat-slideout").sideNav({
  394. menuWidth: 350,
  395. edge: 'right'
  396. });
  397. $("#playlist-slideout").sideNav({
  398. menuWidth: 350,
  399. edge: 'right'
  400. });
  401. $("#users-slideout").sideNav({
  402. menuWidth: 350,
  403. edge: 'right'
  404. });
  405. $("#allowed-slideout").sideNav({
  406. menuWidth: 350,
  407. edge: 'right'
  408. });
  409. $("#playlists-slideout").sideNav({
  410. menuWidth: 350,
  411. edge: 'right'
  412. });
  413. $('.tooltipped').tooltip({delay: 50});
  414. </script>
  415. </template>