mirror of
				https://github.com/Alexander-D-Karpov/akarpov
				synced 2025-10-31 12:17:26 +03:00 
			
		
		
		
	updated music player, added native controls
This commit is contained in:
		
							parent
							
								
									b02a77ec5e
								
							
						
					
					
						commit
						3405b76897
					
				|  | @ -0,0 +1,22 @@ | ||||||
|  | # Generated by Django 4.2.5 on 2023-09-30 11:19 | ||||||
|  | 
 | ||||||
|  | from django.db import migrations, models | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  |     dependencies = [ | ||||||
|  |         ("music", "0008_song_meta"), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name="songinque", | ||||||
|  |             name="name", | ||||||
|  |             field=models.CharField(blank=True, max_length=500), | ||||||
|  |         ), | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name="songinque", | ||||||
|  |             name="status", | ||||||
|  |             field=models.CharField(blank=True, max_length=500, null=True), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| from akarpov.common.models import BaseImageModel | from akarpov.common.models import BaseImageModel | ||||||
| from akarpov.tools.shortener.models import ShortLinkModel | from akarpov.tools.shortener.models import ShortLinkModel | ||||||
| from akarpov.users.services.history import UserHistoryModel | from akarpov.users.services.history import UserHistoryModel | ||||||
|  | from akarpov.utils.cache import cache_model_property | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Author(BaseImageModel, ShortLinkModel): | class Author(BaseImageModel, ShortLinkModel): | ||||||
|  | @ -47,17 +48,35 @@ def get_absolute_url(self): | ||||||
|         return reverse("music:song", kwargs={"slug": self.slug}) |         return reverse("music:song", kwargs={"slug": self.slug}) | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def full_props(self) -> str: |     def full_props(self): | ||||||
|         if self.album and self.authors: |         if self.album_name and self.artists_names: | ||||||
|             return f"{self.album.name} - " + ", ".join( |             return f"{self.album_name} - {self.artists_names}" | ||||||
|                 self.authors.values_list("name", flat=True) |         elif self.album_name: | ||||||
|             ) |             return self.album_name | ||||||
|         elif self.album: |         elif self.artists_names: | ||||||
|             return f"{self.album.name}" |             return self.artists_names | ||||||
|         elif self.album: |         return "" | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def _album_name(self): | ||||||
|  |         if self.album and self.album.name: | ||||||
|  |             return self.album.name | ||||||
|  |         return "" | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def _authors_names(self): | ||||||
|  |         if self.authors: | ||||||
|             return ", ".join(self.authors.values_list("name", flat=True)) |             return ", ".join(self.authors.values_list("name", flat=True)) | ||||||
|         return "" |         return "" | ||||||
| 
 | 
 | ||||||
|  |     @property | ||||||
|  |     def album_name(self): | ||||||
|  |         return cache_model_property(self, "_album_name") | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def artists_names(self): | ||||||
|  |         return cache_model_property(self, "_authors_names") | ||||||
|  | 
 | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return self.name |         return self.name | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| function addEventListener_multi(element, eventNames, handler) { | function addEventListener_multi(element, eventNames, handler) { | ||||||
|   var events = eventNames.split(' '); |     const events = eventNames.split(' '); | ||||||
|   events.forEach(e => element.addEventListener(e, handler, false)); |     events.forEach(e => element.addEventListener(e, handler, false)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Random numbers in a specific range
 | // Random numbers in a specific range
 | ||||||
|  | @ -12,11 +12,11 @@ function getRandom(min, max) { | ||||||
| 
 | 
 | ||||||
| // Position element inside element
 | // Position element inside element
 | ||||||
| function getRelativePos(elm) { | function getRelativePos(elm) { | ||||||
|   var pPos = elm.parentNode.getBoundingClientRect(); // parent pos
 |     const pPos = elm.parentNode.getBoundingClientRect(); // parent pos
 | ||||||
|   var cPos = elm.getBoundingClientRect(); // target pos
 |     const cPos = elm.getBoundingClientRect(); // target pos
 | ||||||
|   var pos = {}; |     const pos = {}; | ||||||
| 
 | 
 | ||||||
|   pos.top    = cPos.top    - pPos.top + elm.parentNode.scrollTop, |     pos.top    = cPos.top    - pPos.top + elm.parentNode.scrollTop, | ||||||
|   pos.right  = cPos.right  - pPos.right, |   pos.right  = cPos.right  - pPos.right, | ||||||
|   pos.bottom = cPos.bottom - pPos.bottom, |   pos.bottom = cPos.bottom - pPos.bottom, | ||||||
|   pos.left   = cPos.left   - pPos.left; |   pos.left   = cPos.left   - pPos.left; | ||||||
|  | @ -25,8 +25,8 @@ function getRelativePos(elm) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function formatTime(val) { | function formatTime(val) { | ||||||
|   var h = 0, m = 0, s; |     let h = 0, m = 0, s; | ||||||
|   val = parseInt(val, 10); |     val = parseInt(val, 10); | ||||||
|   if (val > 60 * 60) { |   if (val > 60 * 60) { | ||||||
|    h = parseInt(val / (60 * 60), 10); |    h = parseInt(val / (60 * 60), 10); | ||||||
|    val -= h * 60 * 60; |    val -= h * 60 * 60; | ||||||
|  | @ -56,8 +56,8 @@ function simp_initTime() { | ||||||
|     simp_audio.removeEventListener('timeupdate', simp_initTime); |     simp_audio.removeEventListener('timeupdate', simp_initTime); | ||||||
| 
 | 
 | ||||||
|     if (simp_isNext) { //auto load next audio
 |     if (simp_isNext) { //auto load next audio
 | ||||||
|       var elem; |         let elem; | ||||||
|       simp_a_index++; |         simp_a_index++; | ||||||
|       if (simp_a_index == simp_a_url.length) { //repeat all audio
 |       if (simp_a_index == simp_a_url.length) { //repeat all audio
 | ||||||
|         simp_a_index = 0; |         simp_a_index = 0; | ||||||
|         elem = simp_a_url[0]; |         elem = simp_a_url[0]; | ||||||
|  | @ -132,7 +132,7 @@ function simp_setAlbum(index) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function simp_changeAudio(elem) { | function simp_changeAudio(elem) { | ||||||
| 	simp_isLoaded = false; |   simp_isLoaded = false; | ||||||
|   simp_controls.querySelector('.simp-prev').disabled = simp_a_index == 0 ? true : false; |   simp_controls.querySelector('.simp-prev').disabled = simp_a_index == 0 ? true : false; | ||||||
|   simp_controls.querySelector('.simp-plause').disabled = simp_auto_load ? true : false; |   simp_controls.querySelector('.simp-plause').disabled = simp_auto_load ? true : false; | ||||||
|   simp_controls.querySelector('.simp-next').disabled = simp_a_index == simp_a_url.length-1 ? true : false; |   simp_controls.querySelector('.simp-next').disabled = simp_a_index == simp_a_url.length-1 ? true : false; | ||||||
|  | @ -144,7 +144,7 @@ function simp_changeAudio(elem) { | ||||||
|   elem = simp_isRandom && simp_isNext ? simp_a_url[getRandom(0, simp_a_url.length-1)] : elem; |   elem = simp_isRandom && simp_isNext ? simp_a_url[getRandom(0, simp_a_url.length-1)] : elem; | ||||||
| 
 | 
 | ||||||
|   // playlist, audio is running
 |   // playlist, audio is running
 | ||||||
|   for (var i = 0; i < simp_a_url.length; i++) { |   for (let i = 0; i < simp_a_url.length; i++) { | ||||||
|     simp_a_url[i].parentNode.classList.remove('simp-active'); |     simp_a_url[i].parentNode.classList.remove('simp-active'); | ||||||
|     if (simp_a_url[i] == elem) { |     if (simp_a_url[i] == elem) { | ||||||
|       simp_a_index = i; |       simp_a_index = i; | ||||||
|  | @ -153,8 +153,8 @@ function simp_changeAudio(elem) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // scrolling to element inside element
 |   // scrolling to element inside element
 | ||||||
|   var simp_active = getRelativePos(simp_source[simp_a_index]); |     const simp_active = getRelativePos(simp_source[simp_a_index]); | ||||||
|   simp_source[simp_a_index].parentNode.scrollTop = simp_active.top; |     simp_source[simp_a_index].parentNode.scrollTop = simp_active.top; | ||||||
| 
 | 
 | ||||||
|   if (simp_auto_load || simp_isPlaying) simp_loadAudio(elem); |   if (simp_auto_load || simp_isPlaying) simp_loadAudio(elem); | ||||||
| 
 | 
 | ||||||
|  | @ -162,6 +162,95 @@ function simp_changeAudio(elem) { | ||||||
|     simp_controls.querySelector('.simp-plause').classList.remove('fa-play'); |     simp_controls.querySelector('.simp-plause').classList.remove('fa-play'); | ||||||
|     simp_controls.querySelector('.simp-plause').classList.add('fa-pause'); |     simp_controls.querySelector('.simp-plause').classList.add('fa-pause'); | ||||||
|   } |   } | ||||||
|  |   // set native audio properties
 | ||||||
|  |   if('mediaSession' in navigator) { | ||||||
|  |     navigator.mediaSession.metadata = new MediaMetadata({ | ||||||
|  |         title: elem.textContent, | ||||||
|  |         artist: elem.dataset.artists, | ||||||
|  |         album: elem.dataset.album, | ||||||
|  |         artwork: [ | ||||||
|  |             { src: elem.dataset.cover, sizes: '96x96', type: 'image/png' }, | ||||||
|  |             { src: elem.dataset.cover, sizes: '128x128', type: 'image/png' }, | ||||||
|  |             { src: elem.dataset.cover, sizes: '192x192', type: 'image/png' }, | ||||||
|  |             { src: elem.dataset.cover, sizes: '256x256', type: 'image/png' }, | ||||||
|  |             { src: elem.dataset.cover, sizes: '384x384', type: 'image/png' }, | ||||||
|  |             { src: elem.dataset.cover, sizes: '512x512', type: 'image/png' } | ||||||
|  |         ] | ||||||
|  |     }); | ||||||
|  |     navigator.mediaSession.setActionHandler('play', () => { | ||||||
|  |     let eles = document.getElementById("simp-plause").classList | ||||||
|  |       if (simp_audio.paused) { | ||||||
|  |         if (!simp_isLoaded) simp_loadAudio(simp_a_url[simp_a_index]); | ||||||
|  |         simp_audio.play(); | ||||||
|  |         simp_isPlaying = true; | ||||||
|  |         eles.remove('fa-play'); | ||||||
|  |         eles.add('fa-pause'); | ||||||
|  |       } else { | ||||||
|  |         simp_audio.pause(); | ||||||
|  |         simp_isPlaying = false; | ||||||
|  |         eles.remove('fa-pause'); | ||||||
|  |         eles.add('fa-play'); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |     navigator.mediaSession.setActionHandler('pause', () => { | ||||||
|  |     let eles = document.getElementById("simp-plause").classList | ||||||
|  |       if (simp_audio.paused) { | ||||||
|  |         if (!simp_isLoaded) simp_loadAudio(simp_a_url[simp_a_index]); | ||||||
|  |         simp_audio.play(); | ||||||
|  |         simp_isPlaying = true; | ||||||
|  |         eles.remove('fa-play'); | ||||||
|  |         eles.add('fa-pause'); | ||||||
|  |       } else { | ||||||
|  |         simp_audio.pause(); | ||||||
|  |         simp_isPlaying = false; | ||||||
|  |         eles.remove('fa-pause'); | ||||||
|  |         eles.add('fa-play'); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |     navigator.mediaSession.setActionHandler("previoustrack", () => { | ||||||
|  |       let eles = document.getElementById("simp-previoustrack") | ||||||
|  |       if (simp_a_index !== 0) { | ||||||
|  |         simp_a_index = simp_a_index-1; | ||||||
|  |         eles.disabled = simp_a_index == 0 ? true : false; | ||||||
|  |       } | ||||||
|  |       simp_audio.removeEventListener('timeupdate', simp_initTime); | ||||||
|  |       simp_changeAudio(simp_a_url[simp_a_index]); | ||||||
|  |       simp_setAlbum(simp_a_index); | ||||||
|  |     }); | ||||||
|  |     navigator.mediaSession.setActionHandler("nexttrack", () => { | ||||||
|  |       let eles = document.getElementById("simp-nexttrack") | ||||||
|  |       if (simp_a_index !== simp_a_url.length-1) { | ||||||
|  |         simp_a_index = simp_a_index+1; | ||||||
|  |         eles.disabled = simp_a_index == simp_a_url.length-1 ? true : false; | ||||||
|  |       } | ||||||
|  |       simp_audio.removeEventListener('timeupdate', simp_initTime); | ||||||
|  |       simp_changeAudio(simp_a_url[simp_a_index]); | ||||||
|  |       simp_setAlbum(simp_a_index); | ||||||
|  |     }); | ||||||
|  |     navigator.mediaSession.setActionHandler('seekbackward', (details) => { | ||||||
|  |         simp_audio.currentTime = simp_audio.currentTime - (details.seekOffset || 10); | ||||||
|  |     }); | ||||||
|  |     navigator.mediaSession.setActionHandler('seekforward', (details) => { | ||||||
|  |         simp_audio.currentTime = simp_audio.currentTime + (details.seekOffset || 10); | ||||||
|  |     }); | ||||||
|  |     navigator.mediaSession.setActionHandler('seekto', (details) => { | ||||||
|  |         if (details.fastSeek && 'fastSeek' in simp_audio) { | ||||||
|  |           simp_audio.fastSeek(details.seekTime); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |         simp_audio.currentTime = details.seekTime; | ||||||
|  |     }); | ||||||
|  |     navigator.mediaSession.setActionHandler('stop', () => { | ||||||
|  |         let eles = document.getElementById("simp-plause").classList | ||||||
|  |         simp_audio.currentTime = 0; | ||||||
|  |         simp_controls.querySelector('.start-time').innerHTML = '00:00'; | ||||||
|  |         if (!simp_isLoaded) simp_loadAudio(simp_a_url[simp_a_index]); | ||||||
|  |         simp_audio.play(); | ||||||
|  |         simp_isPlaying = true; | ||||||
|  |         eles.remove('fa-play'); | ||||||
|  |         eles.add('fa-pause'); | ||||||
|  |     }); | ||||||
|  | } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function simp_startScript() { | function simp_startScript() { | ||||||
|  | @ -210,8 +299,8 @@ function simp_startScript() { | ||||||
| 
 | 
 | ||||||
|   // Controls listeners
 |   // Controls listeners
 | ||||||
|   simp_controls.querySelector('.simp-plauseward').addEventListener('click', function(e) { |   simp_controls.querySelector('.simp-plauseward').addEventListener('click', function(e) { | ||||||
|     var eles = e.target.classList; |       const eles = e.target.classList; | ||||||
|     if (eles.contains('simp-plause')) { |       if (eles.contains('simp-plause')) { | ||||||
|       if (simp_audio.paused) { |       if (simp_audio.paused) { | ||||||
|         if (!simp_isLoaded) simp_loadAudio(simp_a_url[simp_a_index]); |         if (!simp_isLoaded) simp_loadAudio(simp_a_url[simp_a_index]); | ||||||
|         simp_audio.play(); |         simp_audio.play(); | ||||||
|  | @ -240,8 +329,8 @@ function simp_startScript() { | ||||||
| 
 | 
 | ||||||
|   // Audio volume
 |   // Audio volume
 | ||||||
|   simp_volume.addEventListener('click', function(e) { |   simp_volume.addEventListener('click', function(e) { | ||||||
|     var eles = e.target.classList; |       const eles = e.target.classList; | ||||||
|     if (eles.contains('simp-mute')) { |       if (eles.contains('simp-mute')) { | ||||||
|       if (eles.contains('fa-volume-up')) { |       if (eles.contains('fa-volume-up')) { | ||||||
|         eles.remove('fa-volume-up'); |         eles.remove('fa-volume-up'); | ||||||
|         eles.add('fa-volume-off'); |         eles.add('fa-volume-off'); | ||||||
|  | @ -263,8 +352,8 @@ function simp_startScript() { | ||||||
| 
 | 
 | ||||||
|   // Others
 |   // Others
 | ||||||
|   simp_others.addEventListener('click', function(e) { |   simp_others.addEventListener('click', function(e) { | ||||||
|     var eles = e.target.classList; |       const eles = e.target.classList; | ||||||
|     if (eles.contains('simp-plext')) { |       if (eles.contains('simp-plext')) { | ||||||
|       simp_isNext = simp_isNext && !simp_isRandom ? false : true; |       simp_isNext = simp_isNext && !simp_isRandom ? false : true; | ||||||
|       if (!simp_isRandom) simp_isRanext = simp_isRanext ? false : true; |       if (!simp_isRandom) simp_isRanext = simp_isRanext ? false : true; | ||||||
|       eles.contains('simp-active') && !simp_isRandom ? eles.remove('simp-active') : eles.add('simp-active'); |       eles.contains('simp-active') && !simp_isRandom ? eles.remove('simp-active') : eles.add('simp-active'); | ||||||
|  | @ -296,7 +385,7 @@ if (document.querySelector('#simp')) { | ||||||
|   var simp_a_url = simp_playlist.querySelectorAll('[data-src]'); |   var simp_a_url = simp_playlist.querySelectorAll('[data-src]'); | ||||||
|   var simp_a_index = 0; |   var simp_a_index = 0; | ||||||
|   var simp_isPlaying = false; |   var simp_isPlaying = false; | ||||||
|   var simp_isNext = false; //auto play
 |   var simp_isNext = true; //auto play
 | ||||||
|   var simp_isRandom = false; //play random
 |   var simp_isRandom = false; //play random
 | ||||||
|   var simp_isRanext = false; //check if before random starts, simp_isNext value is true
 |   var simp_isRanext = false; //check if before random starts, simp_isNext value is true
 | ||||||
|   var simp_isStream = false; //radio streaming
 |   var simp_isStream = false; //radio streaming
 | ||||||
|  | @ -307,19 +396,19 @@ if (document.querySelector('#simp')) { | ||||||
|     auto_load: false //auto load audio file
 |     auto_load: false //auto load audio file
 | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   var simp_elem = ''; |     let simp_elem = ''; | ||||||
|   simp_elem += '<audio id="audio" preload><source src="" type="audio/mpeg"></audio>'; |     simp_elem += '<audio id="audio" preload><source src="" type="audio/mpeg"></audio>'; | ||||||
|   simp_elem += '<div class="simp-display"><div class="simp-album w-full flex-wrap"><div class="simp-cover"><i class="fa fa-music fa-5x"></i></div><div class="simp-info"><div class="simp-title">Title</div><div class="simp-artist">Artist</div></div></div></div>'; |   simp_elem += '<div class="simp-display"><div class="simp-album w-full flex-wrap"><div class="simp-cover"><i class="fa fa-music fa-5x"></i></div><div class="simp-info"><div class="simp-title">Title</div><div class="simp-artist">Artist</div></div></div></div>'; | ||||||
|   simp_elem += '<div class="simp-controls flex-wrap flex-align">'; |   simp_elem += '<div class="simp-controls flex-wrap flex-align">'; | ||||||
|   simp_elem += '<div class="simp-plauseward flex flex-align"><button type="button" class="simp-prev fa fa-backward" disabled></button><button type="button" class="simp-plause fa fa-play" disabled></button><button type="button" class="simp-next fa fa-forward" disabled></button></div>'; |   simp_elem += '<div class="simp-plauseward flex flex-align"><button type="button" class="simp-prev fa fa-backward" id="simp-previoustrack" disabled></button><button id="simp-plause" type="button" class="simp-plause fa fa-play" disabled></button><button id="simp-nexttrack" type="button" class="simp-next fa fa-forward" disabled></button></div>'; | ||||||
|   simp_elem += '<div class="simp-tracker simp-load"><input class="simp-progress" type="range" min="0" max="100" value="0" disabled/><div class="simp-buffer"></div></div>'; |   simp_elem += '<div class="simp-tracker simp-load"><input class="simp-progress" type="range" min="0" max="100" value="0" disabled/><div class="simp-buffer"></div></div>'; | ||||||
|   simp_elem += '<div class="simp-time flex flex-align"><span class="start-time">00:00</span><span class="simp-slash"> / </span><span class="end-time">00:00</span></div>'; |   simp_elem += '<div class="simp-time flex flex-align"><span class="start-time">00:00</span><span class="simp-slash"> / </span><span class="end-time">00:00</span></div>'; | ||||||
|   simp_elem += '<div class="simp-volume flex flex-align"><button type="button" class="simp-mute fa fa-volume-up"></button><input class="simp-v-slider" type="range" min="0" max="100" value="100"/></div>'; |   simp_elem += '<div class="simp-volume flex flex-align"><button type="button" class="simp-mute fa fa-volume-up"></button><input class="simp-v-slider" type="range" min="0" max="100" value="100"/></div>'; | ||||||
|   simp_elem += '<div class="simp-others flex flex-align"><button type="button" class="simp-plext fa fa-play-circle" title="Auto Play"></button><button type="button" class="simp-random fa fa-random" title="Random"></button><div class="simp-shide"><button type="button" class="simp-shide-top fa fa-caret-up" title="Show/Hide Album"></button><button type="button" class="simp-shide-bottom fa fa-caret-down" title="Show/Hide Playlist"></button></div></div>'; |   simp_elem += '<div class="simp-others flex flex-align"><button type="button"  class="simp-plext fa fa-play-circle simp-active" title="Auto Play" ></button><button type="button" class="simp-random fa fa-random" title="Random"></button><div class="simp-shide"><button type="button" class="simp-shide-top fa fa-caret-up" title="Show/Hide Album"></button><button type="button" class="simp-shide-bottom fa fa-caret-down" title="Show/Hide Playlist"></button></div></div>'; | ||||||
|   simp_elem += '</div>'; //simp-controls
 |   simp_elem += '</div>'; //simp-controls
 | ||||||
| 
 | 
 | ||||||
|   var simp_player = document.createElement('div'); |     const simp_player = document.createElement('div'); | ||||||
|   simp_player.classList.add('simp-player'); |     simp_player.classList.add('simp-player'); | ||||||
|   simp_player.innerHTML = simp_elem; |   simp_player.innerHTML = simp_elem; | ||||||
|   ap_simp.insertBefore(simp_player, simp_playlist); |   ap_simp.insertBefore(simp_player, simp_playlist); | ||||||
|   simp_startScript(); |   simp_startScript(); | ||||||
|  |  | ||||||
|  | @ -5,11 +5,11 @@ | ||||||
|     {% endblock %} |     {% endblock %} | ||||||
|   {% block content %} |   {% block content %} | ||||||
|     <div class="d-flex align-items-center justify-content-center"> |     <div class="d-flex align-items-center justify-content-center"> | ||||||
|         <div class="simple-audio-player flex-column" id="simp" data-config='{"shide_top":false,"shide_btm":false,"auto_load":false}'> |         <div class="simple-audio-player flex-column" id="simp" data-config='{"shide_top":false,"shide_btm":false,"auto_load":true}'> | ||||||
|           <div class="simp-playlist"> |           <div class="simp-playlist"> | ||||||
|             <ul> |             <ul> | ||||||
|               {% for song in song_list %} |               {% for song in song_list %} | ||||||
|             <li><span class="simp-source" {% if song.image %}data-cover="{{ song.image.url }}"{% endif %} data-src="{{ song.file.url }}">{{ song.name }}</span><span class="simp-desc">{{ song.full_props }}</span></li> |             <li><span class="simp-source" {% if song.image %}data-cover="{{ song.image.url }}"{% endif %} data-artists="{{ song.artists_names }}" data-albumn="{{ song.album_name }}" data-src="{{ song.file.url }}">{{ song.name }}</span><span class="simp-desc">{{ song.full_props }}</span></li> | ||||||
|               {% endfor %} |               {% endfor %} | ||||||
|             </ul> |             </ul> | ||||||
|           </div> |           </div> | ||||||
|  |  | ||||||
							
								
								
									
										2894
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2894
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -82,7 +82,6 @@ xvfbwrapper = "^0.2.9" | ||||||
| vtk = "^9.2.6" | vtk = "^9.2.6" | ||||||
| ffmpeg-python = "^0.2.0" | ffmpeg-python = "^0.2.0" | ||||||
| cairosvg = "^2.7.0" | cairosvg = "^2.7.0" | ||||||
| textract = "^1.6.5" |  | ||||||
| spotipy = "2.16.1" | spotipy = "2.16.1" | ||||||
| django-robots = "^5.0" | django-robots = "^5.0" | ||||||
| django-tables2 = "^2.5.3" | django-tables2 = "^2.5.3" | ||||||
|  | @ -109,6 +108,7 @@ pytest-asyncio = "^0.21.1" | ||||||
| pytest-lambda = "^2.2.0" | pytest-lambda = "^2.2.0" | ||||||
| pgvector = "^0.2.2" | pgvector = "^0.2.2" | ||||||
| pycld2 = "^0.41" | pycld2 = "^0.41" | ||||||
|  | textract = "^1.6.5" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| [build-system] | [build-system] | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user