VulpesOS/assets/webapps/music.gaiamobile.org/js/db.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

39 lines
No EOL
8.5 KiB
JavaScript

;;;'use strict';var Database=(function(){var playlists=[{id:'shuffle-all',index:'metadata.title',direction:'next',shuffle:true},{id:'highest-rated',index:'metadata.rated',direction:'prev',shuffle:false},{id:'recently-added',index:'date',direction:'prev',shuffle:false},{id:'most-played',index:'metadata.played',direction:'prev',shuffle:false},{id:'least-played',index:'metadata.played',direction:'next',shuffle:false}];var status={upgrading:false,unavailable:false,enumerable:false,ready:false};var resolveEnumerable;var enumerable=new Promise((resolve)=>{resolveEnumerable=resolve;});var resolveReady;var ready=new Promise((resolve)=>{resolveReady=resolve;});var dbChange=debounce(()=>service.broadcast('databaseChange'),500);document.addEventListener('DOMRetranslated',dbChange);function debounce(fn,ms){var timeout;return()=>{var args=arguments;clearTimeout(timeout);timeout=setTimeout(()=>fn.apply(this,args),ms);};}
var musicdb;function init(){var excludedFolders=['Ringtones','Notifications','Alarms'];var excludeFilter=new RegExp('^(/[^/]*/)?('+excludedFolders.join('|')+')/','i');musicdb=new MediaDB('music',metadataParserWrapper,{indexes:['metadata.album','metadata.artist','metadata.title','metadata.rated','metadata.played','date'],excludeFilter:excludeFilter,batchSize:1,autoscan:false,updateRecord:updateRecord,reparsedRecord:reparsedRecord,version:3});function metadataParserWrapper(file,onsuccess,onerror){var scripts=['/js/metadata/metadata_scripts.js','/js/metadata/album_art.js'];LazyLoader.load(scripts).then(()=>{return AudioMetadata.parse(file);}).then((metadata)=>{return AlbumArt.process(file,metadata);}).then(onsuccess,onerror);}
var startedReparsing=false;function updateRecord(record,oldVersion,newVersion){if(oldVersion===2){record.needsReparse=true;if(!startedReparsing){startedReparsing=true;service.broadcast('databaseUpgrade');}}
return record.metadata;}
function reparsedRecord(oldMetadata,newMetadata){newMetadata.rated=oldMetadata.rated;newMetadata.played=oldMetadata.played;return newMetadata;}
musicdb.onupgrading=function(event){status.upgrading=true;status.enumerable=false;status.ready=false;service.broadcast('databaseUpgrade');};musicdb.onunavailable=function(event){var reason=event.detail===MediaDB.UNMOUNTED?'pluggedin':event.detail;onUnavailable(reason);};musicdb.oncardremoved=function(){service.broadcast('databaseChange');};function onUnavailable(reason){status.unavailable=reason;status.enumerable=false;status.ready=false;enumerable=new Promise((resolve)=>{resolveEnumerable=resolve;});ready=new Promise((resolve)=>{resolveReady=resolve;});service.broadcast('databaseUnavailable',reason);}
musicdb.onenumerable=onEnumerable;var refreshOnReady=false;function onEnumerable(){if(musicdb.state===MediaDB.READY){onReady();}else{musicdb.onready=onReady;}
status.upgrading=false;status.enumerable=true;resolveEnumerable();service.broadcast('databaseEnumerable');}
function onReady(){musicdb.scan();status.unavailable=false;status.enumerable=true;status.ready=true;resolveEnumerable();resolveReady();service.broadcast('databaseReady',refreshOnReady);refreshOnReady=true;}
var filesDeletedWhileScanning=0;var filesFoundWhileScanning=0;var filesFoundBatch=0;var scanning=false;var SCAN_UPDATE_BATCH_SIZE=25;var DELETE_BATCH_TIMEOUT=500;var deleteTimer=null;var firstScanDone=false;musicdb.onscanstart=function(){scanning=true;filesFoundWhileScanning=0;filesFoundBatch=0;filesDeletedWhileScanning=0;};musicdb.onscanend=function(){scanning=false;service.broadcast('scanStopped');if(filesFoundBatch>0||filesDeletedWhileScanning>0){filesFoundWhileScanning=0;filesFoundBatch=0;filesDeletedWhileScanning=0;dbChange();}
if(!firstScanDone){firstScanDone=true;window.performance.mark('fullyLoaded');}};musicdb.oncreated=function(event){if(scanning){var metadata=event.detail[0].metadata;var n=event.detail.length;filesFoundWhileScanning+=n;filesFoundBatch+=n;service.broadcast('scanProgress',{count:filesFoundWhileScanning,artist:metadata.artist,title:metadata.title});if(filesFoundBatch>SCAN_UPDATE_BATCH_SIZE){filesFoundBatch=0;dbChange();}}
else{dbChange();}};musicdb.ondeleted=function(event){if(scanning){filesDeletedWhileScanning+=event.detail.length;}
else{if(deleteTimer){clearTimeout(deleteTimer);}
deleteTimer=setTimeout(function(){deleteTimer=null;dbChange();},DELETE_BATCH_TIMEOUT);}};}
function incrementPlayCount(fileinfo){return new Promise((resolve)=>{fileinfo.metadata.played++;musicdb.updateMetadata(fileinfo.name,{played:fileinfo.metadata.played},resolve);});}
function setSongRating(fileinfo,rated){return new Promise((resolve)=>{fileinfo.metadata.rated=rated;musicdb.updateMetadata(fileinfo.name,{rated:fileinfo.metadata.rated},resolve);});}
function getFile(fileinfo,decrypt=false){return new Promise((resolve,reject)=>{ready.then(()=>{musicdb.getFile(fileinfo.name,(file)=>{if(file){resolve(file);}else{reject('unable to get file: '+fileinfo.name);}});});}).then((blob)=>{if(!decrypt||!fileinfo.metadata.locked){return blob;}
return new Promise(function(resolve,reject){LazyLoader.load('/shared/js/omadrm/fl.js').then(()=>{ForwardLock.getKey(function(secret){ForwardLock.unlockBlob(secret,blob,resolve,null,reject);});});});});}
function getFileInfo(filename){return new Promise(function(resolve,reject){ready.then(()=>musicdb.getFileInfo(filename,(r)=>{r?resolve(r):reject('Undefined result for '+filename);},reject)).catch((e)=>reject(e));});}
function enumerate(...args){return enumerable.then(()=>musicdb.enumerate(...args));}
function enumerateAll(...args){return enumerable.then(()=>musicdb.enumerateAll(...args));}
function advancedEnumerate(...args){return enumerable.then(()=>musicdb.advancedEnumerate(...args));}
function count(...args){return enumerable.then(()=>musicdb.count(...args));}
function cancelEnumeration(handle){musicdb.cancelEnumeration(handle);}
IntlHelper.define('titleSorter','collator',{usage:'sort',sensitivity:'base',numeric:true,ignorePunctuation:true});function _localeSort(collator,a,b){return collator.compare(a,b);}
function _sortArtist(collator,a,b){return _localeSort(collator,a.metadata.artist,b.metadata.artist);}
function _sortAlbum(collator,a,b){return _localeSort(collator,a.metadata.album,b.metadata.album);}
function _sortTitle(collator,a,b){return _localeSort(collator,a.metadata.title,b.metadata.title);}
function _sortTrack(collator,a,b){return(a.metadata.discnum-b.metadata.discnum)||(a.metadata.tracknum-b.metadata.tracknum)||_sortTitle(collator,a,b);}
function artists(){return new Promise((resolve)=>{enumerateAll('metadata.artist',null,'nextunique',(artists)=>{artists.sort(_sortArtist.bind(null,IntlHelper.get('titleSorter')));resolve(artists);});});}
function albums(){return new Promise((resolve)=>{enumerateAll('metadata.album',null,'nextunique',(albums)=>{albums.sort(_sortAlbum.bind(null,IntlHelper.get('titleSorter')));resolve(albums);});});}
function songs(){return new Promise((resolve)=>{enumerateAll('metadata.title',null,'next',(songs)=>{songs.sort(_sortTitle.bind(null,IntlHelper.get('titleSorter')));resolve(songs);});});}
function totalCount(){return new Promise((resolve)=>{count('metadata.title',null,(count)=>resolve(count));});}
function artist(name){return new Promise((resolve)=>{var range=IDBKeyRange.only(name);enumerateAll('metadata.artist',range,'next',(songs)=>{var collator=IntlHelper.get('titleSorter');songs.sort((a,b)=>{return _sortAlbum(collator,a,b)||_sortTrack(collator,a,b);});resolve(songs);});});}
function album(name){return new Promise((resolve)=>{var range=IDBKeyRange.only(name);enumerateAll('metadata.album',range,'next',(songs)=>{songs.sort(_sortTrack.bind(null,IntlHelper.get('titleSorter')));resolve(songs);});});}
function search(key,query,callback){return enumerable.then(()=>{if(!query){callback(null);return;}
return LazyLoader.load('/shared/js/text_normalizer.js').then(()=>{query=Normalizer.toAscii(query.toLocaleLowerCase());var direction=(key==='title')?'next':'nextunique';return musicdb.enumerate('metadata.'+key,null,direction,(result)=>{if(result===null){callback(result);return;}
var resultLowerCased=result.metadata[key].toLocaleLowerCase();if(Normalizer.toAscii(resultLowerCased).indexOf(query)!==-1){callback(result);}});});});}
return{init:init,incrementPlayCount:incrementPlayCount,setSongRating:setSongRating,getFile:getFile,getFileInfo:getFileInfo,enumerate:enumerate,enumerateAll:enumerateAll,advancedEnumerate:advancedEnumerate,count:count,cancelEnumeration:cancelEnumeration,artists:artists,albums:albums,songs:songs,totalCount:totalCount,artist:artist,album:album,search:search,playlists:playlists,status:status,get initialScanComplete(){return musicdb.initialScanComplete;}};})();