| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839 | 
							- <template>
 
- 	<div>
 
- 		<modal title="Edit Song" class="song-modal">
 
- 			<div slot="body">
 
- 				<div class="left-section">
 
- 					<div class="top-section">
 
- 						<div class="player-section">
 
- 							<div id="player"></div>
 
- 							<canvas
 
- 								id="durationCanvas"
 
- 								height="20"
 
- 								width="530"
 
- 							></canvas>
 
- 							<div class="player-footer">
 
- 								<div class="player-footer-left">
 
- 									<i
 
- 										class="material-icons player-play-pause"
 
- 										v-on:click="settings('play')"
 
- 										v-if="video.paused"
 
- 										>play_arrow</i
 
- 									>
 
- 									<i
 
- 										class="material-icons player-play-pause"
 
- 										v-on:click="settings('pause')"
 
- 										v-if="!video.paused"
 
- 										>pause</i
 
- 									>
 
- 									<i
 
- 										class="material-icons player-stop"
 
- 										v-on:click="settings('stop')"
 
- 										>stop</i
 
- 									>
 
- 									<i
 
- 										class="material-icons player-fast-forward"
 
- 										v-on:click="
 
- 											settings('skipToLast10Secs')
 
- 										"
 
- 										>fast_forward</i
 
- 									>
 
- 								</div>
 
- 								<div class="player-footer-center">
 
- 									<img src="/assets/social/youtube.svg" />
 
- 									<span>
 
- 										<span>
 
- 											{{ youtubeVideoCurrentTime }}
 
- 										</span>
 
- 										/
 
- 										<span>
 
- 											{{ youtubeVideoDuration }}
 
- 											{{ youtubeVideoNote }}
 
- 										</span>
 
- 									</span>
 
- 								</div>
 
- 								<div class="player-footer-right">
 
- 									<input
 
- 										type="range"
 
- 										id="volumeSlider"
 
- 										min="0"
 
- 										max="100"
 
- 										class="active"
 
- 										v-on:change="changeVolume()"
 
- 										v-on:input="changeVolume()"
 
- 									/>
 
- 								</div>
 
- 							</div>
 
- 						</div>
 
- 						<img
 
- 							class="thumbnail-preview"
 
- 							:src="editing.song.thumbnail"
 
- 							onerror="this.src='/assets/notes-transparent.png'"
 
- 						/>
 
- 					</div>
 
- 					<div class="edit-section">
 
- 						<div class="control is-grouped">
 
- 							<div class="title-container">
 
- 								<label class="label">Title</label>
 
- 								<p class="control has-addons">
 
- 									<input
 
- 										class="input"
 
- 										type="text"
 
- 										v-model="editing.song.title"
 
- 									/>
 
- 									<button
 
- 										class="button album-get-button"
 
- 										v-on:click="getAlbumData('title')"
 
- 									>
 
- 										<i class="material-icons">album</i>
 
- 									</button>
 
- 								</p>
 
- 							</div>
 
- 							<div class="duration-container">
 
- 								<label class="label">Duration</label>
 
- 								<p class="control has-addons">
 
- 									<input
 
- 										class="input"
 
- 										type="text"
 
- 										v-model.number="editing.song.duration"
 
- 									/>
 
- 									<button
 
- 										class="button duration-fill-button"
 
- 										v-on:click="fillDuration()"
 
- 									>
 
- 										<i class="material-icons">sync</i>
 
- 									</button>
 
- 								</p>
 
- 							</div>
 
- 							<div class="skip-duration-container">
 
- 								<label class="label">Skip duration</label>
 
- 								<p class="control">
 
- 									<input
 
- 										class="input"
 
- 										type="text"
 
- 										v-model.number="
 
- 											editing.song.skipDuration
 
- 										"
 
- 									/>
 
- 								</p>
 
- 							</div>
 
- 						</div>
 
- 						<div class="control is-grouped">
 
- 							<div class="album-art-container">
 
- 								<label class="label">Album art</label>
 
- 								<p class="control has-addons">
 
- 									<input
 
- 										class="input"
 
- 										type="text"
 
- 										v-model="editing.song.thumbnail"
 
- 									/>
 
- 									<button
 
- 										class="button album-get-button"
 
- 										v-on:click="getAlbumData('albumArt')"
 
- 									>
 
- 										<i class="material-icons">album</i>
 
- 									</button>
 
- 								</p>
 
- 							</div>
 
- 						</div>
 
- 						<div class="control is-grouped">
 
- 							<div class="artists-container">
 
- 								<label class="label">Artists</label>
 
- 								<p class="control has-addons">
 
- 									<input
 
- 										class="input"
 
- 										type="text"
 
- 										id="new-artist"
 
- 										v-model="artistInputValue"
 
- 										v-on:blur="blurArtistInput()"
 
- 										v-on:focus="focusArtistInput()"
 
- 										v-on:keydown="keydownArtistInput()"
 
- 									/>
 
- 									<button
 
- 										class="button album-get-button"
 
- 										v-on:click="getAlbumData('artists')"
 
- 									>
 
- 										<i class="material-icons">album</i>
 
- 									</button>
 
- 									<button
 
- 										class="button is-info add-button"
 
- 										v-on:click="addTag('artists')"
 
- 									>
 
- 										<i class="material-icons">add</i>
 
- 									</button>
 
- 								</p>
 
- 								<div
 
- 									class="autosuggest-container"
 
- 									v-if="
 
- 										(artistInputFocussed ||
 
- 											artistAutosuggestContainerFocussed) &&
 
- 											artistAutosuggestItems.length > 0
 
- 									"
 
- 									@mouseover="focusArtistContainer()"
 
- 									@mouseleave="blurArtistContainer()"
 
- 								>
 
- 									<span
 
- 										class="autosuggest-item"
 
- 										tabindex="0"
 
- 										v-on:click="
 
- 											selectArtistAutosuggest(item)
 
- 										"
 
- 										v-for="(item,
 
- 										index) in artistAutosuggestItems"
 
- 										:key="index"
 
- 										>{{ item }}</span
 
- 									>
 
- 								</div>
 
- 								<div class="list-container">
 
- 									<div
 
- 										class="list-item"
 
- 										v-for="(artist, index) in editing.song
 
- 											.artists"
 
- 										:key="index"
 
- 									>
 
- 										<div
 
- 											class="list-item-circle"
 
- 											v-on:click="
 
- 												removeTag('artists', index)
 
- 											"
 
- 										>
 
- 											<i class="material-icons">close</i>
 
- 										</div>
 
- 										<p>{{ artist }}</p>
 
- 									</div>
 
- 								</div>
 
- 							</div>
 
- 							<div class="genres-container">
 
- 								<label class="label">
 
- 									<span>Genres</span>
 
- 									<i
 
- 										class="material-icons"
 
- 										@click="toggleGenreHelper"
 
- 										@dblclick="resetGenreHelper"
 
- 										>info</i
 
- 									>
 
- 								</label>
 
- 								<p class="control has-addons">
 
- 									<input
 
- 										class="input"
 
- 										type="text"
 
- 										id="new-genre"
 
- 										v-model="genreInputValue"
 
- 										v-on:blur="blurGenreInput()"
 
- 										v-on:focus="focusGenreInput()"
 
- 										v-on:keydown="keydownGenreInput()"
 
- 									/>
 
- 									<button
 
- 										class="button album-get-button"
 
- 										v-on:click="getAlbumData('genres')"
 
- 									>
 
- 										<i class="material-icons">album</i>
 
- 									</button>
 
- 									<button
 
- 										class="button is-info add-button"
 
- 										v-on:click="addTag('genres')"
 
- 									>
 
- 										<i class="material-icons">add</i>
 
- 									</button>
 
- 								</p>
 
- 								<div
 
- 									class="autosuggest-container"
 
- 									v-if="
 
- 										(genreInputFocussed ||
 
- 											genreAutosuggestContainerFocussed) &&
 
- 											genreAutosuggestItems.length > 0
 
- 									"
 
- 									@mouseover="focusGenreContainer()"
 
- 									@mouseleave="blurGenreContainer()"
 
- 								>
 
- 									<span
 
- 										class="autosuggest-item"
 
- 										tabindex="0"
 
- 										v-on:click="
 
- 											selectGenreAutosuggest(item)
 
- 										"
 
- 										v-for="(item,
 
- 										index) in genreAutosuggestItems"
 
- 										:key="index"
 
- 										>{{ item }}</span
 
- 									>
 
- 								</div>
 
- 								<div class="list-container">
 
- 									<div
 
- 										class="list-item"
 
- 										v-for="(genre, index) in editing.song
 
- 											.genres"
 
- 										:key="index"
 
- 									>
 
- 										<div
 
- 											class="list-item-circle"
 
- 											v-on:click="
 
- 												removeTag('genres', index)
 
- 											"
 
- 										>
 
- 											<i class="material-icons">close</i>
 
- 										</div>
 
- 										<p>{{ genre }}</p>
 
- 									</div>
 
- 								</div>
 
- 							</div>
 
- 							<div class="youtube-id-container">
 
- 								<label class="label">YouTube ID</label>
 
- 								<p class="control">
 
- 									<input
 
- 										class="input"
 
- 										type="text"
 
- 										v-model="editing.song.songId"
 
- 									/>
 
- 								</p>
 
- 							</div>
 
- 						</div>
 
- 					</div>
 
- 				</div>
 
- 				<div class="right-section">
 
- 					<div class="api-section">
 
- 						<div
 
- 							class="selected-discogs-info"
 
- 							v-if="!editing.song.discogs"
 
- 						>
 
- 							<p class="selected-discogs-info-none">None</p>
 
- 						</div>
 
- 						<div
 
- 							class="selected-discogs-info"
 
- 							v-if="editing.song.discogs"
 
- 						>
 
- 							<div class="top-container">
 
- 								<img
 
- 									:src="editing.song.discogs.album.albumArt"
 
- 								/>
 
- 								<div class="right-container">
 
- 									<p class="album-title">
 
- 										{{ editing.song.discogs.album.title }}
 
- 									</p>
 
- 									<div class="bottom-row">
 
- 										<p class="type-year">
 
- 											<span>{{
 
- 												editing.song.discogs.album.type
 
- 											}}</span>
 
- 											•
 
- 											<span>{{
 
- 												editing.song.discogs.album.year
 
- 											}}</span>
 
- 										</p>
 
- 									</div>
 
- 								</div>
 
- 							</div>
 
- 							<div class="bottom-container">
 
- 								<p class="bottom-container-field">
 
- 									Artists:
 
- 									<span>{{
 
- 										editing.song.discogs.album.artists.join(
 
- 											", "
 
- 										)
 
- 									}}</span>
 
- 								</p>
 
- 								<p class="bottom-container-field">
 
- 									Genres:
 
- 									<span>{{
 
- 										editing.song.discogs.album.genres.join(
 
- 											", "
 
- 										)
 
- 									}}</span>
 
- 								</p>
 
- 								<p class="bottom-container-field">
 
- 									Data quality:
 
- 									<span>{{
 
- 										editing.song.discogs.dataQuality
 
- 									}}</span>
 
- 								</p>
 
- 								<p class="bottom-container-field">
 
- 									Track:
 
- 									<span
 
- 										>{{
 
- 											editing.song.discogs.track.position
 
- 										}}.
 
- 										{{
 
- 											editing.song.discogs.track.title
 
- 										}}</span
 
- 									>
 
- 								</p>
 
- 							</div>
 
- 						</div>
 
- 						<p class="control is-expanded">
 
- 							<label class="label">Search query</label>
 
- 							<input
 
- 								class="input"
 
- 								type="text"
 
- 								v-model="discogsQuery"
 
- 								@change="onDiscogsQueryChange"
 
- 							/>
 
- 						</p>
 
- 						<button
 
- 							class="button is-info is-fullwidth"
 
- 							v-on:click="searchDiscogsForPage(1)"
 
- 						>
 
- 							Search
 
- 						</button>
 
- 						<label
 
- 							class="label"
 
- 							v-if="discogs.apiResults.length > 0"
 
- 							>API results</label
 
- 						>
 
- 						<div
 
- 							class="api-results-container"
 
- 							v-if="discogs.apiResults.length > 0"
 
- 						>
 
- 							<div
 
- 								class="api-result"
 
- 								v-for="(result, index) in discogs.apiResults"
 
- 								:key="index"
 
- 							>
 
- 								<div class="top-container">
 
- 									<img :src="result.album.albumArt" />
 
- 									<div class="right-container">
 
- 										<p class="album-title">
 
- 											{{ result.album.title }}
 
- 										</p>
 
- 										<div class="bottom-row">
 
- 											<img
 
- 												src="/assets/arrow_up.svg"
 
- 												v-if="result.expanded"
 
- 												v-on:click="
 
- 													toggleAPIResult(index)
 
- 												"
 
- 											/>
 
- 											<img
 
- 												src="/assets/arrow_down.svg"
 
- 												v-if="!result.expanded"
 
- 												v-on:click="
 
- 													toggleAPIResult(index)
 
- 												"
 
- 											/>
 
- 											<p class="type-year">
 
- 												<span>{{
 
- 													result.album.type
 
- 												}}</span>
 
- 												•
 
- 												<span>{{
 
- 													result.album.year
 
- 												}}</span>
 
- 											</p>
 
- 										</div>
 
- 									</div>
 
- 								</div>
 
- 								<div
 
- 									class="bottom-container"
 
- 									v-if="result.expanded"
 
- 								>
 
- 									<p class="bottom-container-field">
 
- 										Artists:
 
- 										<span>{{
 
- 											result.album.artists.join(", ")
 
- 										}}</span>
 
- 									</p>
 
- 									<p class="bottom-container-field">
 
- 										Genres:
 
- 										<span>{{
 
- 											result.album.genres.join(", ")
 
- 										}}</span>
 
- 									</p>
 
- 									<p class="bottom-container-field">
 
- 										Data quality:
 
- 										<span>{{ result.dataQuality }}</span>
 
- 									</p>
 
- 									<div class="tracks">
 
- 										<div
 
- 											class="track"
 
- 											tabindex="0"
 
- 											v-for="(track,
 
- 											trackIndex) in result.tracks"
 
- 											:key="trackIndex"
 
- 											v-on:click="
 
- 												selectTrack(index, trackIndex)
 
- 											"
 
- 										>
 
- 											<span>{{ track.position }}.</span>
 
- 											<p>{{ track.title }}</p>
 
- 										</div>
 
- 									</div>
 
- 								</div>
 
- 							</div>
 
- 						</div>
 
- 						<button
 
- 							v-if="
 
- 								discogs.apiResults.length > 0 &&
 
- 									!discogs.disableLoadMore &&
 
- 									discogs.page < discogs.pages
 
- 							"
 
- 							class="button is-fullwidth is-info discogs-load-more"
 
- 							@click="loadNextDiscogsPage()"
 
- 						>
 
- 							Load more...
 
- 						</button>
 
- 					</div>
 
- 				</div>
 
- 			</div>
 
- 			<div slot="footer" class="footer-buttons">
 
- 				<button
 
- 					class="button is-success"
 
- 					v-on:click="save(editing.song, false)"
 
- 				>
 
- 					<i class="material-icons save-changes">done</i>
 
- 					<span> Save</span>
 
- 				</button>
 
- 				<button
 
- 					class="button is-success"
 
- 					v-on:click="save(editing.song, true)"
 
- 				>
 
- 					<i class="material-icons save-changes">done</i>
 
- 					<span> Save and close</span>
 
- 				</button>
 
- 				<button
 
- 					class="button is-danger"
 
- 					v-on:click="
 
- 						closeModal({ sector: 'admin', modal: 'editSong' })
 
- 					"
 
- 				>
 
- 					<span> Close</span>
 
- 				</button>
 
- 			</div>
 
- 		</modal>
 
- 		<div
 
- 			id="genre-helper-container"
 
- 			v-bind:style="{
 
- 				width: genreHelper.width + 'px',
 
- 				height: genreHelper.height + 'px',
 
- 				top: genreHelper.top + 'px',
 
- 				left: genreHelper.left + 'px'
 
- 			}"
 
- 			v-if="genreHelper.shown"
 
- 			@mousedown="onResizeGenreHelper"
 
- 		>
 
- 			<div
 
- 				class="genre-helper-header"
 
- 				@mousedown="onDragGenreHelper"
 
- 			></div>
 
- 			<div class="genre-helper-body">
 
- 				<span>Blues</span><span>Country</span><span>Disco</span
 
- 				><span>Funk</span><span>Hip-Hop</span><span>Jazz</span
 
- 				><span>Metal</span><span>Oldies</span><span>Other</span
 
- 				><span>Pop</span><span>Rap</span><span>Reggae</span
 
- 				><span>Rock</span><span>Techno</span><span>Trance</span
 
- 				><span>Classical</span><span>Instrumental</span
 
- 				><span>House</span><span>Electronic</span
 
- 				><span>Christian Rap</span><span>Lo-Fi</span><span>Musical</span
 
- 				><span>Rock 'n' Roll</span><span>Opera</span
 
- 				><span>Drum & Bass</span><span>Club-House</span
 
- 				><span>Indie</span><span>Heavy Metal</span
 
- 				><span>Christian rock</span><span>Dubstep</span>
 
- 			</div>
 
- 		</div>
 
- 	</div>
 
- </template>
 
- <script>
 
- import { mapState, mapActions } from "vuex";
 
- import Toast from "toasters";
 
- import io from "../../io";
 
- import validation from "../../validation";
 
- import Modal from "./Modal.vue";
 
- export default {
 
- 	components: { Modal },
 
- 	data() {
 
- 		return {
 
- 			discogsQuery: "",
 
- 			youtubeVideoDuration: 0.0,
 
- 			youtubeVideoCurrentTime: 0.0,
 
- 			youtubeVideoNote: "",
 
- 			useHTTPS: false,
 
- 			discogs: {
 
- 				apiResults: [],
 
- 				page: 1,
 
- 				pages: 1,
 
- 				disableLoadMore: false
 
- 			},
 
- 			artistInputValue: "",
 
- 			genreInputValue: "",
 
- 			artistInputFocussed: false,
 
- 			genreInputFocussed: false,
 
- 			genreAutosuggestContainerFocussed: false,
 
- 			artistAutosuggestContainerFocussed: false,
 
- 			keydownArtistInputTimeout: 0,
 
- 			keydownGenreInputTimeout: 0,
 
- 			artistAutosuggestItems: [],
 
- 			genreAutosuggestItems: [],
 
- 			genreHelper: {
 
- 				width: 200,
 
- 				height: 200,
 
- 				top: 0,
 
- 				left: 0,
 
- 				shown: false,
 
- 				pos1: 0,
 
- 				pos2: 0,
 
- 				pos3: 0,
 
- 				pos4: 0
 
- 			},
 
- 			genres: [
 
- 				"Blues",
 
- 				"Country",
 
- 				"Disco",
 
- 				"Funk",
 
- 				"Hip-Hop",
 
- 				"Jazz",
 
- 				"Metal",
 
- 				"Oldies",
 
- 				"Other",
 
- 				"Pop",
 
- 				"Rap",
 
- 				"Reggae",
 
- 				"Rock",
 
- 				"Techno",
 
- 				"Trance",
 
- 				"Classical",
 
- 				"Instrumental",
 
- 				"House",
 
- 				"Electronic",
 
- 				"Christian Rap",
 
- 				"Lo-Fi",
 
- 				"Musical",
 
- 				"Rock 'n' Roll",
 
- 				"Opera",
 
- 				"Drum & Bass",
 
- 				"Club-House",
 
- 				"Indie",
 
- 				"Heavy Metal",
 
- 				"Christian rock",
 
- 				"Dubstep"
 
- 			]
 
- 		};
 
- 	},
 
- 	computed: {
 
- 		...mapState("admin/songs", {
 
- 			video: state => state.video,
 
- 			editing: state => state.editing,
 
- 			songs: state => state.songs
 
- 		}),
 
- 		...mapState("modals", {
 
- 			modals: state => state.modals.admin
 
- 		})
 
- 	},
 
- 	watch: {
 
- 		/* eslint-disable */
 
- 		"editing.song.duration": function() {
 
- 			this.drawCanvas();
 
- 		},
 
- 		"editing.song.skipDuration": function() {
 
- 			this.drawCanvas();
 
- 		}
 
- 		/* eslint-enable */
 
- 	},
 
- 	methods: {
 
- 		save(songToCopy, close) {
 
- 			const song = JSON.parse(JSON.stringify(songToCopy));
 
- 			if (!song.title)
 
- 				return new Toast({
 
- 					content: "Please fill in all fields",
 
- 					timeout: 8000
 
- 				});
 
- 			if (!song.thumbnail)
 
- 				return new Toast({
 
- 					content: "Please fill in all fields",
 
- 					timeout: 8000
 
- 				});
 
- 			// Duration
 
- 			if (
 
- 				Number(song.skipDuration) + Number(song.duration) >
 
- 				this.youtubeVideoDuration
 
- 			) {
 
- 				return new Toast({
 
- 					content:
 
- 						"Duration can't be higher than the length of the video",
 
- 					timeout: 8000
 
- 				});
 
- 			}
 
- 			// Title
 
- 			if (!validation.isLength(song.title, 1, 100))
 
- 				return new Toast({
 
- 					content: "Title must have between 1 and 100 characters.",
 
- 					timeout: 8000
 
- 				});
 
- 			// Artists
 
- 			if (song.artists.length < 1 || song.artists.length > 10)
 
- 				return new Toast({
 
- 					content:
 
- 						"Invalid artists. You must have at least 1 artist and a maximum of 10 artists.",
 
- 					timeout: 8000
 
- 				});
 
- 			let error;
 
- 			song.artists.forEach(artist => {
 
- 				if (!validation.isLength(artist, 1, 64)) {
 
- 					error = "Artist must have between 1 and 64 characters.";
 
- 					return error;
 
- 				}
 
- 				if (artist === "NONE") {
 
- 					error =
 
- 						'Invalid artist format. Artists are not allowed to be named "NONE".';
 
- 					return error;
 
- 				}
 
- 				return false;
 
- 			});
 
- 			if (error) return new Toast({ content: error, timeout: 8000 });
 
- 			// Genres
 
- 			error = undefined;
 
- 			song.genres.forEach(genre => {
 
- 				if (!validation.isLength(genre, 1, 32)) {
 
- 					error = "Genre must have between 1 and 32 characters.";
 
- 					return error;
 
- 				}
 
- 				if (!validation.regex.ascii.test(genre)) {
 
- 					error =
 
- 						"Invalid genre format. Only ascii characters are allowed.";
 
- 					return error;
 
- 				}
 
- 				return false;
 
- 			});
 
- 			if (song.genres.length < 1 || song.genres.length > 16)
 
- 				error = "You must have between 1 and 16 genres.";
 
- 			if (error) return new Toast({ content: error, timeout: 8000 });
 
- 			// Thumbnail
 
- 			if (!validation.isLength(song.thumbnail, 1, 256))
 
- 				return new Toast({
 
- 					content:
 
- 						"Thumbnail must have between 8 and 256 characters.",
 
- 					timeout: 8000
 
- 				});
 
- 			if (this.useHTTPS && song.thumbnail.indexOf("https://") !== 0) {
 
- 				return new Toast({
 
- 					content: 'Thumbnail must start with "https://".',
 
- 					timeout: 8000
 
- 				});
 
- 			}
 
- 			if (
 
- 				!this.useHTTPS &&
 
- 				(song.thumbnail.indexOf("http://") !== 0 &&
 
- 					song.thumbnail.indexOf("https://") !== 0)
 
- 			) {
 
- 				return new Toast({
 
- 					content: 'Thumbnail must start with "http://".',
 
- 					timeout: 8000
 
- 				});
 
- 			}
 
- 			return this.socket.emit(
 
- 				`${this.editing.type}.update`,
 
- 				song._id,
 
- 				song,
 
- 				res => {
 
- 					new Toast({ content: res.message, timeout: 4000 });
 
- 					if (res.status === "success") {
 
- 						this.songs.forEach(originalSong => {
 
- 							const updatedSong = song;
 
- 							if (originalSong._id === updatedSong._id) {
 
- 								Object.keys(originalSong).forEach(n => {
 
- 									updatedSong[n] = originalSong[n];
 
- 									return originalSong[n];
 
- 								});
 
- 							}
 
- 						});
 
- 					}
 
- 					if (close)
 
- 						this.closeModal({
 
- 							sector: "admin",
 
- 							modal: "editSong"
 
- 						});
 
- 				}
 
- 			);
 
- 		},
 
- 		toggleAPIResult(index) {
 
- 			const apiResult = this.discogs.apiResults[index];
 
- 			if (apiResult.expanded === true) apiResult.expanded = false;
 
- 			else if (apiResult.gotMoreInfo === true) apiResult.expanded = true;
 
- 			else {
 
- 				fetch(apiResult.album.resourceUrl)
 
- 					.then(response => {
 
- 						return response.json();
 
- 					})
 
- 					.then(data => {
 
- 						apiResult.album.artists = [];
 
- 						apiResult.album.artistIds = [];
 
- 						const artistRegex = new RegExp(" \\([0-9]+\\)$");
 
- 						apiResult.dataQuality = data.data_quality;
 
- 						data.artists.forEach(artist => {
 
- 							apiResult.album.artists.push(
 
- 								artist.name.replace(artistRegex, "")
 
- 							);
 
- 							apiResult.album.artistIds.push(artist.id);
 
- 						});
 
- 						apiResult.tracks = data.tracklist.map(track => {
 
- 							return {
 
- 								position: track.position,
 
- 								title: track.title
 
- 							};
 
- 						});
 
- 						apiResult.expanded = true;
 
- 						apiResult.gotMoreInfo = true;
 
- 					});
 
- 			}
 
- 		},
 
- 		fillDuration() {
 
- 			this.editing.song.duration =
 
- 				this.youtubeVideoDuration - this.editing.song.skipDuration;
 
- 		},
 
- 		getAlbumData(type) {
 
- 			if (!this.editing.song.discogs) return;
 
- 			if (type === "title")
 
- 				this.updateSongField({
 
- 					field: "title",
 
- 					value: this.editing.song.discogs.track.title
 
- 				});
 
- 			if (type === "albumArt")
 
- 				this.updateSongField({
 
- 					field: "thumbnail",
 
- 					value: this.editing.song.discogs.album.albumArt
 
- 				});
 
- 			if (type === "genres")
 
- 				this.updateSongField({
 
- 					field: "genres",
 
- 					value: JSON.parse(
 
- 						JSON.stringify(this.editing.song.discogs.album.genres)
 
- 					)
 
- 				});
 
- 			if (type === "artists")
 
- 				this.updateSongField({
 
- 					field: "artists",
 
- 					value: JSON.parse(
 
- 						JSON.stringify(this.editing.song.discogs.album.artists)
 
- 					)
 
- 				});
 
- 		},
 
- 		searchDiscogsForPage(page) {
 
- 			const query = this.discogsQuery;
 
- 			this.socket.emit("apis.searchDiscogs", query, page, res => {
 
- 				if (res.status === "success") {
 
- 					if (page === 1)
 
- 						new Toast({
 
- 							content: `Successfully searched. Got ${res.results.length} results.`,
 
- 							timeout: 4000
 
- 						});
 
- 					else
 
- 						new Toast({
 
- 							content: `Successfully got ${res.results.length} more results.`,
 
- 							timeout: 4000
 
- 						});
 
- 					if (page === 1) {
 
- 						this.discogs.apiResults = [];
 
- 					}
 
- 					this.discogs.pages = res.pages;
 
- 					this.discogs.apiResults = this.discogs.apiResults.concat(
 
- 						res.results.map(result => {
 
- 							const type =
 
- 								result.type.charAt(0).toUpperCase() +
 
- 								result.type.slice(1);
 
- 							return {
 
- 								expanded: false,
 
- 								gotMoreInfo: false,
 
- 								album: {
 
- 									id: result.id,
 
- 									title: result.title,
 
- 									type,
 
- 									year: result.year,
 
- 									genres: result.genre,
 
- 									albumArt: result.cover_image,
 
- 									resourceUrl: result.resource_url
 
- 								}
 
- 							};
 
- 						})
 
- 					);
 
- 					this.discogs.page = page;
 
- 					this.discogs.disableLoadMore = false;
 
- 				} else new Toast({ content: res.message, timeout: 8000 });
 
- 			});
 
- 		},
 
- 		loadNextDiscogsPage() {
 
- 			this.discogs.disableLoadMore = true;
 
- 			this.searchDiscogsForPage(this.discogs.page + 1);
 
- 		},
 
- 		onDiscogsQueryChange() {
 
- 			this.discogs.page = 1;
 
- 			this.discogs.pages = 1;
 
- 			this.discogs.apiResults = [];
 
- 			this.discogs.disableLoadMore = false;
 
- 		},
 
- 		selectTrack(apiResultIndex, trackIndex) {
 
- 			const apiResult = JSON.parse(
 
- 				JSON.stringify(this.discogs.apiResults[apiResultIndex])
 
- 			);
 
- 			apiResult.track = apiResult.tracks[trackIndex];
 
- 			delete apiResult.tracks;
 
- 			delete apiResult.expanded;
 
- 			delete apiResult.gotMoreInfo;
 
- 			this.selectDiscogsInfo(apiResult);
 
- 		},
 
- 		blurArtistInput() {
 
- 			this.artistInputFocussed = false;
 
- 		},
 
- 		focusArtistInput() {
 
- 			this.artistInputFocussed = true;
 
- 		},
 
- 		blurArtistContainer() {
 
- 			this.artistAutosuggestContainerFocussed = false;
 
- 		},
 
- 		focusArtistContainer() {
 
- 			this.artistAutosuggestContainerFocussed = true;
 
- 		},
 
- 		keydownArtistInput() {
 
- 			clearTimeout(this.keydownArtistInputTimeout);
 
- 			this.keydownArtistInputTimeout = setTimeout(() => {
 
- 				// Do things here to query the artist
 
- 			}, 1000);
 
- 		},
 
- 		selectArtistAutosuggest(value) {
 
- 			this.artistInputValue = value;
 
- 		},
 
- 		blurGenreInput() {
 
- 			this.genreInputFocussed = false;
 
- 		},
 
- 		focusGenreInput() {
 
- 			this.genreInputFocussed = true;
 
- 		},
 
- 		blurGenreContainer() {
 
- 			this.genreAutosuggestContainerFocussed = false;
 
- 		},
 
- 		focusGenreContainer() {
 
- 			this.genreAutosuggestContainerFocussed = true;
 
- 		},
 
- 		keydownGenreInput() {
 
- 			clearTimeout(this.keydownGenreInputTimeout);
 
- 			this.keydownGenreInputTimeout = setTimeout(() => {
 
- 				if (this.genreInputValue.length > 1) {
 
- 					this.genreAutosuggestItems = this.genres.filter(genre => {
 
- 						return genre
 
- 							.toLowerCase()
 
- 							.startsWith(this.genreInputValue.toLowerCase());
 
- 					});
 
- 				} else this.genreAutosuggestItems = [];
 
- 			}, 1000);
 
- 		},
 
- 		selectGenreAutosuggest(value) {
 
- 			this.genreInputValue = value;
 
- 		},
 
- 		settings(type) {
 
- 			switch (type) {
 
- 				default:
 
- 					break;
 
- 				case "stop":
 
- 					this.stopVideo();
 
- 					this.pauseVideo(true);
 
- 					break;
 
- 				case "pause":
 
- 					this.pauseVideo(true);
 
- 					break;
 
- 				case "play":
 
- 					this.pauseVideo(false);
 
- 					break;
 
- 				case "skipToLast10Secs":
 
- 					if (this.video.paused) this.pauseVideo(false);
 
- 					this.video.player.seekTo(
 
- 						this.editing.song.duration -
 
- 							10 +
 
- 							this.editing.song.skipDuration
 
- 					);
 
- 					break;
 
- 			}
 
- 		},
 
- 		changeVolume() {
 
- 			const volume = document.getElementById("volumeSlider").value;
 
- 			localStorage.setItem("volume", volume);
 
- 			this.video.player.setVolume(volume);
 
- 			if (volume > 0) this.video.player.unMute();
 
- 		},
 
- 		addTag(type) {
 
- 			if (type === "genres") {
 
- 				const genre = document
 
- 					.getElementById("new-genre")
 
- 					.value.toLowerCase()
 
- 					.trim();
 
- 				if (this.editing.song.genres.indexOf(genre) !== -1)
 
- 					return new Toast({
 
- 						content: "Genre already exists",
 
- 						timeout: 3000
 
- 					});
 
- 				if (genre) {
 
- 					this.editing.song.genres.push(genre);
 
- 					document.getElementById("new-genre").value = "";
 
- 					return false;
 
- 				}
 
- 				return new Toast({
 
- 					content: "Genre cannot be empty",
 
- 					timeout: 3000
 
- 				});
 
- 			}
 
- 			if (type === "artists") {
 
- 				const artist = document.getElementById("new-artist").value;
 
- 				if (this.editing.song.artists.indexOf(artist) !== -1)
 
- 					return new Toast({
 
- 						content: "Artist already exists",
 
- 						timeout: 3000
 
- 					});
 
- 				if (document.getElementById("new-artist").value !== "") {
 
- 					this.editing.song.artists.push(artist);
 
- 					document.getElementById("new-artist").value = "";
 
- 					return false;
 
- 				}
 
- 				return new Toast({
 
- 					content: "Artist cannot be empty",
 
- 					timeout: 3000
 
- 				});
 
- 			}
 
- 			return false;
 
- 		},
 
- 		removeTag(type, index) {
 
- 			if (type === "genres") this.editing.song.genres.splice(index, 1);
 
- 			else if (type === "artists")
 
- 				this.editing.song.artists.splice(index, 1);
 
- 		},
 
- 		drawCanvas() {
 
- 			const canvasElement = document.getElementById("durationCanvas");
 
- 			const ctx = canvasElement.getContext("2d");
 
- 			const videoDuration = Number(this.youtubeVideoDuration);
 
- 			const skipDuration = Number(this.editing.song.skipDuration);
 
- 			const duration = Number(this.editing.song.duration);
 
- 			const afterDuration = videoDuration - (skipDuration + duration);
 
- 			const width = 530;
 
- 			const currentTime = this.video.player.getCurrentTime();
 
- 			const widthSkipDuration = (skipDuration / videoDuration) * width;
 
- 			const widthDuration = (duration / videoDuration) * width;
 
- 			const widthAfterDuration = (afterDuration / videoDuration) * width;
 
- 			const widthCurrentTime = (currentTime / videoDuration) * width;
 
- 			const skipDurationColor = "#F42003";
 
- 			const durationColor = "#03A9F4";
 
- 			const afterDurationColor = "#41E841";
 
- 			const currentDurationColor = "#3b25e8";
 
- 			ctx.fillStyle = skipDurationColor;
 
- 			ctx.fillRect(0, 0, widthSkipDuration, 20);
 
- 			ctx.fillStyle = durationColor;
 
- 			ctx.fillRect(widthSkipDuration, 0, widthDuration, 20);
 
- 			ctx.fillStyle = afterDurationColor;
 
- 			ctx.fillRect(
 
- 				widthSkipDuration + widthDuration,
 
- 				0,
 
- 				widthAfterDuration,
 
- 				20
 
- 			);
 
- 			ctx.fillStyle = currentDurationColor;
 
- 			ctx.fillRect(widthCurrentTime, 0, 1, 20);
 
- 		},
 
- 		onDragGenreHelper(e) {
 
- 			const e1 = e || window.event;
 
- 			e1.preventDefault();
 
- 			this.genreHelper.pos3 = e1.clientX;
 
- 			this.genreHelper.pos4 = e1.clientY;
 
- 			document.onmousemove = e => {
 
- 				const e2 = e || window.event;
 
- 				e2.preventDefault();
 
- 				// calculate the new cursor position:
 
- 				this.genreHelper.pos1 = this.genreHelper.pos3 - e.clientX;
 
- 				this.genreHelper.pos2 = this.genreHelper.pos4 - e.clientY;
 
- 				this.genreHelper.pos3 = e.clientX;
 
- 				this.genreHelper.pos4 = e.clientY;
 
- 				// set the element's new position:
 
- 				this.genreHelper.top -= this.genreHelper.pos2;
 
- 				this.genreHelper.left -= this.genreHelper.pos1;
 
- 			};
 
- 			document.onmouseup = () => {
 
- 				document.onmouseup = null;
 
- 				document.onmousemove = null;
 
- 				this.saveGenreHelper();
 
- 			};
 
- 		},
 
- 		onResizeGenreHelper(e) {
 
- 			if (e.target.id !== "genre-helper-container") return;
 
- 			document.onmouseup = () => {
 
- 				document.onmouseup = null;
 
- 				const { height, width } = e.target.style;
 
- 				this.genreHelper.height = Number(
 
- 					height
 
- 						.split("")
 
- 						.splice(0, height.length - 2)
 
- 						.join("")
 
- 				);
 
- 				this.genreHelper.width = Number(
 
- 					width
 
- 						.split("")
 
- 						.splice(0, width.length - 2)
 
- 						.join("")
 
- 				);
 
- 				this.saveGenreHelper();
 
- 			};
 
- 		},
 
- 		toggleGenreHelper() {
 
- 			this.genreHelper.shown = !this.genreHelper.shown;
 
- 			this.saveGenreHelper();
 
- 		},
 
- 		resetGenreHelper() {
 
- 			this.genreHelper.top = 0;
 
- 			this.genreHelper.left = 0;
 
- 			this.genreHelper.width = 200;
 
- 			this.genreHelper.height = 200;
 
- 			this.saveGenreHelper();
 
- 		},
 
- 		saveGenreHelper() {
 
- 			localStorage.setItem(
 
- 				"genreHelper",
 
- 				JSON.stringify({
 
- 					height: this.genreHelper.height,
 
- 					width: this.genreHelper.width,
 
- 					top: this.genreHelper.top,
 
- 					left: this.genreHelper.left,
 
- 					shown: this.genreHelper.shown
 
- 				})
 
- 			);
 
- 		},
 
- 		...mapActions("admin/songs", [
 
- 			"stopVideo",
 
- 			"loadVideoById",
 
- 			"pauseVideo",
 
- 			"getCurrentTime",
 
- 			"editSong",
 
- 			"updateSongField",
 
- 			"selectDiscogsInfo"
 
- 		]),
 
- 		...mapActions("modals", ["closeModal"])
 
- 	},
 
- 	mounted() {
 
- 		// if (this.modals.editSong = false) this.video.player.stopVideo();
 
- 		// this.loadVideoById(
 
- 		//   this.editing.song.songId,
 
- 		//   this.editing.song.skipDuration
 
- 		// );
 
- 		if (localStorage.genreHelper) {
 
- 			const genreHelper = JSON.parse(localStorage.getItem("genreHelper"));
 
- 			this.genreHelper.height = genreHelper.height;
 
- 			this.genreHelper.width = genreHelper.width;
 
- 			this.genreHelper.top = genreHelper.top;
 
- 			this.genreHelper.left = genreHelper.left;
 
- 			this.genreHelper.shown = genreHelper.shown;
 
- 		}
 
- 		this.discogsQuery = this.editing.song.title;
 
- 		lofig.get("cookie.secure").then(useHTTPS => {
 
- 			this.useHTTPS = useHTTPS;
 
- 		});
 
- 		io.getSocket(socket => {
 
- 			this.socket = socket;
 
- 		});
 
- 		this.interval = setInterval(() => {
 
- 			if (
 
- 				this.editing.song.duration !== -1 &&
 
- 				this.video.paused === false &&
 
- 				this.playerReady &&
 
- 				this.video.player.getCurrentTime() -
 
- 					this.editing.song.skipDuration >
 
- 					this.editing.song.duration
 
- 			) {
 
- 				this.video.paused = false;
 
- 				this.video.player.stopVideo();
 
- 				this.drawCanvas();
 
- 			}
 
- 			if (this.playerReady) {
 
- 				this.youtubeVideoCurrentTime = this.video.player
 
- 					.getCurrentTime()
 
- 					.toFixed(3);
 
- 			}
 
- 			if (this.video.paused === false) this.drawCanvas();
 
- 		}, 200);
 
- 		this.video.player = new window.YT.Player("player", {
 
- 			height: 298,
 
- 			width: 530,
 
- 			videoId: this.editing.song.songId,
 
- 			playerVars: {
 
- 				controls: 0,
 
- 				iv_load_policy: 3,
 
- 				rel: 0,
 
- 				showinfo: 0,
 
- 				autoplay: 1
 
- 			},
 
- 			startSeconds: this.editing.song.skipDuration,
 
- 			events: {
 
- 				onReady: () => {
 
- 					let volume = parseInt(localStorage.getItem("volume"));
 
- 					volume = typeof volume === "number" ? volume : 20;
 
- 					console.log(`Seekto: ${this.editing.song.skipDuration}`);
 
- 					this.video.player.seekTo(this.editing.song.skipDuration);
 
- 					this.video.player.setVolume(volume);
 
- 					if (volume > 0) this.video.player.unMute();
 
- 					this.youtubeVideoDuration = this.video.player.getDuration();
 
- 					this.youtubeVideoNote = "(~)";
 
- 					this.playerReady = true;
 
- 					this.drawCanvas();
 
- 				},
 
- 				onStateChange: event => {
 
- 					this.drawCanvas();
 
- 					if (event.data === 1) {
 
- 						if (!this.video.autoPlayed) {
 
- 							this.video.autoPlayed = true;
 
- 							return this.video.player.stopVideo();
 
- 						}
 
- 						this.video.paused = false;
 
- 						let youtubeDuration = this.video.player.getDuration();
 
- 						this.youtubeVideoDuration = youtubeDuration;
 
- 						this.youtubeVideoNote = "";
 
- 						if (this.editing.song.duration === -1)
 
- 							this.editing.song.duration = youtubeDuration;
 
- 						youtubeDuration -= this.editing.song.skipDuration;
 
- 						if (this.editing.song.duration > youtubeDuration + 1) {
 
- 							this.video.player.stopVideo();
 
- 							this.video.paused = true;
 
- 							return new Toast({
 
- 								content:
 
- 									"Video can't play. Specified duration is bigger than the YouTube song duration.",
 
- 								timeout: 4000
 
- 							});
 
- 						}
 
- 						if (this.editing.song.duration <= 0) {
 
- 							this.video.player.stopVideo();
 
- 							this.video.paused = true;
 
- 							return new Toast({
 
- 								content:
 
- 									"Video can't play. Specified duration has to be more than 0 seconds.",
 
- 								timeout: 4000
 
- 							});
 
- 						}
 
- 						if (
 
- 							this.video.player.getCurrentTime() <
 
- 							this.editing.song.skipDuration
 
- 						) {
 
- 							return this.video.player.seekTo(
 
- 								this.editing.song.skipDuration
 
- 							);
 
- 						}
 
- 					} else if (event.data === 2) {
 
- 						this.video.paused = true;
 
- 					}
 
- 					return false;
 
- 				}
 
- 			}
 
- 		});
 
- 		let volume = parseInt(localStorage.getItem("volume"));
 
- 		document.getElementById("volumeSlider").value = volume =
 
- 			typeof volume === "number" ? volume : 20;
 
- 	},
 
- 	beforeDestroy() {
 
- 		this.playerReady = false;
 
- 		clearInterval(this.interval);
 
- 	}
 
- };
 
- </script>
 
- <style lang="scss">
 
- @import "styles/global.scss";
 
- #genre-helper-container {
 
- 	background-color: white;
 
- 	position: fixed;
 
- 	z-index: 10000000;
 
- 	resize: both;
 
- 	overflow: auto;
 
- 	border: 1px solid #d3d3d3;
 
- 	min-height: 50px !important;
 
- 	min-width: 50px !important;
 
- 	.genre-helper-header {
 
- 		cursor: move;
 
- 		z-index: 100000001;
 
- 		background-color: $musareBlue;
 
- 		padding: 10px;
 
- 		display: block;
 
- 		height: 10px;
 
- 		width: 100%;
 
- 	}
 
- 	.genre-helper-body {
 
- 		display: flex;
 
- 		flex-wrap: wrap;
 
- 		justify-content: space-evenly;
 
- 		span {
 
- 			padding: 3px 6px;
 
- 		}
 
- 	}
 
- }
 
- .song-modal {
 
- 	.modal-card-title {
 
- 		text-align: center;
 
- 		margin-left: 24px;
 
- 	}
 
- 	.modal-card {
 
- 		width: 1160px;
 
- 		height: 100%;
 
- 		.modal-card-body {
 
- 			padding: 16px;
 
- 		}
 
- 	}
 
- }
 
- </style>
 
- <style lang="scss" scoped>
 
- @import "styles/global.scss";
 
- .modal-card-body > div {
 
- 	display: flex;
 
- 	height: 100%;
 
- }
 
- .left-section {
 
- 	display: flex;
 
- 	flex-direction: column;
 
- 	margin-right: 16px;
 
- 	.top-section {
 
- 		display: flex;
 
- 		.player-section {
 
- 			width: 530px;
 
- 			display: flex;
 
- 			flex-direction: column;
 
- 			.player-footer {
 
- 				background-color: #f4f4f4;
 
- 				border: 1px rgba(163, 224, 255, 0.75) solid;
 
- 				border-radius: 0px 0px 5px 5px;
 
- 				display: flex;
 
- 				justify-content: space-between;
 
- 				height: 54px;
 
- 				> * {
 
- 					width: 33.3%;
 
- 					display: flex;
 
- 					align-items: center;
 
- 				}
 
- 				.player-footer-left {
 
- 					flex: 1;
 
- 					.material-icons {
 
- 						font-size: 38px;
 
- 						cursor: pointer;
 
- 					}
 
- 					.player-play-pause {
 
- 						color: $musareBlue;
 
- 					}
 
- 					.player-stop {
 
- 						color: $red;
 
- 					}
 
- 					.player-fast-forward {
 
- 						color: $green;
 
- 					}
 
- 				}
 
- 				.player-footer-center {
 
- 					justify-content: center;
 
- 					align-items: center;
 
- 					flex: 2;
 
- 					font-size: 21px;
 
- 					font-weight: 400;
 
- 					img {
 
- 						height: 21px;
 
- 						margin-right: 12px;
 
- 						filter: invert(26%) sepia(54%) saturate(6317%)
 
- 							hue-rotate(2deg) brightness(92%) contrast(115%);
 
- 					}
 
- 				}
 
- 				.player-footer-right {
 
- 					justify-content: right;
 
- 					flex: 1;
 
- 					#volumeSlider {
 
- 						width: 126px;
 
- 						margin-right: 10px;
 
- 						background-color: #f4f4f4;
 
- 					}
 
- 				}
 
- 			}
 
- 		}
 
- 		.thumbnail-preview {
 
- 			width: 189px;
 
- 			height: 189px;
 
- 			margin-left: 16px;
 
- 		}
 
- 	}
 
- 	.edit-section {
 
- 		width: 735px;
 
- 		background-color: #f4f4f4;
 
- 		border: 1px rgba(163, 224, 255, 0.75) solid;
 
- 		margin-top: 16px;
 
- 		flex: 1;
 
- 		overflow: auto;
 
- 		border-radius: 5px;
 
- 		.album-get-button {
 
- 			background-color: $purple;
 
- 			color: white;
 
- 			width: 32px;
 
- 			text-align: center;
 
- 			border-width: 0;
 
- 		}
 
- 		.duration-fill-button {
 
- 			background-color: $red;
 
- 			color: $white;
 
- 			width: 32px;
 
- 			text-align: center;
 
- 			border-width: 0;
 
- 		}
 
- 		.add-button {
 
- 			background-color: $musareBlue !important;
 
- 			width: 32px;
 
- 			i {
 
- 				font-size: 32px;
 
- 			}
 
- 		}
 
- 		> div {
 
- 			margin: 16px;
 
- 		}
 
- 		input {
 
- 			width: 100%;
 
- 		}
 
- 		.title-container {
 
- 			width: calc((100% - 32px) / 2);
 
- 		}
 
- 		.duration-container {
 
- 			margin-right: 16px;
 
- 			margin-left: 16px;
 
- 			width: calc((100% - 32px) / 4);
 
- 		}
 
- 		.skip-duration-container {
 
- 			width: calc((100% - 32px) / 4);
 
- 		}
 
- 		.album-art-container {
 
- 			width: 100%;
 
- 		}
 
- 		.artists-container {
 
- 			width: calc((100% - 32px) / 3);
 
- 			position: relative;
 
- 		}
 
- 		.genres-container {
 
- 			width: calc((100% - 32px) / 3);
 
- 			margin-left: 16px;
 
- 			margin-right: 16px;
 
- 			position: relative;
 
- 			label {
 
- 				display: flex;
 
- 				i {
 
- 					font-size: 15px;
 
- 					align-self: center;
 
- 					margin-left: 5px;
 
- 					color: $musareBlue;
 
- 					cursor: pointer;
 
- 					-webkit-user-select: none;
 
- 					-moz-user-select: none;
 
- 					-ms-user-select: none;
 
- 					user-select: none;
 
- 				}
 
- 			}
 
- 		}
 
- 		.youtube-id-container {
 
- 			width: calc((100% - 32px) / 3);
 
- 		}
 
- 		.list-item-circle {
 
- 			background-color: $musareBlue;
 
- 			width: 16px;
 
- 			height: 16px;
 
- 			border-radius: 8px;
 
- 			cursor: pointer;
 
- 			margin-right: 8px;
 
- 			float: left;
 
- 			-webkit-touch-callout: none;
 
- 			-webkit-user-select: none;
 
- 			-khtml-user-select: none;
 
- 			-moz-user-select: none;
 
- 			-ms-user-select: none;
 
- 			user-select: none;
 
- 			i {
 
- 				color: $musareBlue;
 
- 				font-size: 14px;
 
- 				margin-left: 1px;
 
- 			}
 
- 		}
 
- 		.list-item-circle:hover,
 
- 		.list-item-circle:focus {
 
- 			i {
 
- 				color: white;
 
- 			}
 
- 		}
 
- 		.list-item > p {
 
- 			line-height: 16px;
 
- 			word-wrap: break-word;
 
- 			width: calc(100% - 24px);
 
- 			left: 24px;
 
- 			float: left;
 
- 			margin-bottom: 8px;
 
- 		}
 
- 		.list-item:last-child > p {
 
- 			margin-bottom: 0;
 
- 		}
 
- 		.autosuggest-container {
 
- 			position: absolute;
 
- 			background: white;
 
- 			width: calc(100% + 1px);
 
- 			top: 57px;
 
- 			z-index: 200;
 
- 			overflow: auto;
 
- 			max-height: 100%;
 
- 			clear: both;
 
- 			.autosuggest-item {
 
- 				padding: 8px;
 
- 				display: block;
 
- 				border: 1px solid #dbdbdb;
 
- 				margin-top: -1px;
 
- 				line-height: 16px;
 
- 				cursor: pointer;
 
- 				-webkit-user-select: none;
 
- 				-ms-user-select: none;
 
- 				-moz-user-select: none;
 
- 				user-select: none;
 
- 			}
 
- 			.autosuggest-item:hover,
 
- 			.autosuggest-item:focus {
 
- 				background-color: #eee;
 
- 			}
 
- 			.autosuggest-item:first-child {
 
- 				border-top: none;
 
- 			}
 
- 			.autosuggest-item:last-child {
 
- 				border-radius: 0 0 3px 3px;
 
- 			}
 
- 		}
 
- 	}
 
- }
 
- .right-section {
 
- 	display: flex;
 
- 	flex-wrap: wrap;
 
- 	.api-section {
 
- 		width: 376px;
 
- 		background-color: #f4f4f4;
 
- 		border: 1px rgba(163, 224, 255, 0.75) solid;
 
- 		border-radius: 5px;
 
- 		padding: 16px;
 
- 		overflow: auto;
 
- 		height: 100%;
 
- 		> label {
 
- 			margin-top: 12px;
 
- 		}
 
- 		.top-container {
 
- 			display: flex;
 
- 			img {
 
- 				height: 85px;
 
- 				width: 85px;
 
- 			}
 
- 			.right-container {
 
- 				padding: 8px;
 
- 				display: flex;
 
- 				flex-direction: column;
 
- 				flex: 1;
 
- 				.album-title {
 
- 					flex: 1;
 
- 					font-weight: 600;
 
- 				}
 
- 				.bottom-row {
 
- 					display: flex;
 
- 					flex-flow: row;
 
- 					line-height: 15px;
 
- 					img {
 
- 						height: 15px;
 
- 						align-self: end;
 
- 						flex: 1;
 
- 						user-select: none;
 
- 						-moz-user-select: none;
 
- 						-ms-user-select: none;
 
- 						-webkit-user-select: none;
 
- 						cursor: pointer;
 
- 					}
 
- 					p {
 
- 						text-align: right;
 
- 					}
 
- 					.type-year {
 
- 						font-size: 13px;
 
- 						align-self: end;
 
- 					}
 
- 				}
 
- 			}
 
- 		}
 
- 		.bottom-container {
 
- 			padding: 12px;
 
- 			.bottom-container-field {
 
- 				line-height: 16px;
 
- 				margin-bottom: 8px;
 
- 				font-weight: 600;
 
- 				span {
 
- 					font-weight: 400;
 
- 				}
 
- 			}
 
- 			.bottom-container-field:last-of-type {
 
- 				margin-bottom: 0;
 
- 			}
 
- 		}
 
- 		.selected-discogs-info {
 
- 			background-color: white;
 
- 			border: 1px solid $purple;
 
- 			border-radius: 5px;
 
- 			margin-bottom: 16px;
 
- 			.selected-discogs-info-none {
 
- 				font-size: 18px;
 
- 				text-align: center;
 
- 			}
 
- 			.bottom-row > p {
 
- 				flex: 1;
 
- 			}
 
- 		}
 
- 		.api-result {
 
- 			background-color: white;
 
- 			border: 0.5px solid $musareBlue;
 
- 			border-radius: 5px;
 
- 			margin-bottom: 16px;
 
- 		}
 
- 		button {
 
- 			background-color: $musareBlue !important;
 
- 		}
 
- 		.tracks {
 
- 			margin-top: 12px;
 
- 			.track:first-child {
 
- 				margin-top: 0;
 
- 				border-radius: 3px 3px 0 0;
 
- 			}
 
- 			.track:last-child {
 
- 				border-radius: 0 0 3px 3px;
 
- 			}
 
- 			.track {
 
- 				border: 0.5px solid black;
 
- 				margin-top: -1px;
 
- 				line-height: 16px;
 
- 				display: flex;
 
- 				cursor: pointer;
 
- 				span {
 
- 					font-weight: 600;
 
- 					display: inline-block;
 
- 					margin-top: 7px;
 
- 					margin-bottom: 7px;
 
- 					margin-left: 7px;
 
- 				}
 
- 				p {
 
- 					display: inline-block;
 
- 					margin: 7px;
 
- 					flex: 1;
 
- 				}
 
- 			}
 
- 			.track:hover,
 
- 			.track:focus {
 
- 				background-color: #f4f4f4;
 
- 			}
 
- 		}
 
- 		.discogs-load-more {
 
- 			margin-bottom: 8px;
 
- 		}
 
- 	}
 
- }
 
- .footer-buttons {
 
- 	margin-left: auto;
 
- 	margin-right: auto;
 
- }
 
- input[type="range"] {
 
- 	-webkit-appearance: none;
 
- 	width: 100%;
 
- 	margin: 8.5px 0;
 
- }
 
- input[type="range"]:focus {
 
- 	outline: none;
 
- }
 
- input[type="range"]::-webkit-slider-runnable-track {
 
- 	width: 100%;
 
- 	height: 3px;
 
- 	cursor: pointer;
 
- 	box-shadow: none;
 
- 	background: #7e7e7e;
 
- 	border-radius: none;
 
- 	border: none;
 
- }
 
- input[type="range"]::-webkit-slider-thumb {
 
- 	box-shadow: none;
 
- 	border: none;
 
- 	height: 20px;
 
- 	width: 20px;
 
- 	border-radius: 100px;
 
- 	background: #03a9f4;
 
- 	cursor: pointer;
 
- 	-webkit-appearance: none;
 
- 	margin-top: -8.5px;
 
- }
 
- input[type="range"]:focus::-webkit-slider-runnable-track {
 
- 	background: #7e7e7e;
 
- }
 
- input[type="range"]::-moz-range-track {
 
- 	width: 100%;
 
- 	height: 3px;
 
- 	cursor: pointer;
 
- 	box-shadow: none;
 
- 	background: #7e7e7e;
 
- 	border-radius: none;
 
- 	border: none;
 
- }
 
- input[type="range"]::-moz-range-thumb {
 
- 	box-shadow: none;
 
- 	border: none;
 
- 	height: 20px;
 
- 	width: 20px;
 
- 	border-radius: 100px;
 
- 	background: #03a9f4;
 
- 	cursor: pointer;
 
- }
 
- input[type="range"]::-ms-track {
 
- 	width: 100%;
 
- 	height: 3px;
 
- 	cursor: pointer;
 
- 	background: transparent;
 
- 	border-color: transparent;
 
- 	color: transparent;
 
- }
 
- input[type="range"]::-ms-fill-lower {
 
- 	background: #717171;
 
- 	border: none;
 
- 	border-radius: none;
 
- 	box-shadow: none;
 
- }
 
- input[type="range"]::-ms-fill-upper {
 
- 	background: #7e7e7e;
 
- 	border: none;
 
- 	border-radius: none;
 
- 	box-shadow: none;
 
- }
 
- input[type="range"]::-ms-thumb {
 
- 	box-shadow: none;
 
- 	border: none;
 
- 	height: 20px;
 
- 	width: 20px;
 
- 	border-radius: 100px;
 
- 	background: #03a9f4;
 
- 	cursor: pointer;
 
- 	height: 3px;
 
- }
 
- input[type="range"]:focus::-ms-fill-lower {
 
- 	background: #7e7e7e;
 
- }
 
- input[type="range"]:focus::-ms-fill-upper {
 
- 	background: #7e7e7e;
 
- }
 
- </style>
 
 
  |