From 8761ea7fb9183dccd726a9e40f452161b0b72455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pauli=20J=C3=A4rvinen?= Date: Sat, 30 Dec 2023 20:34:06 +0200 Subject: [PATCH] Register the playlist file tab view in the Files app also on NC28 The old API for registration is no longer available on NC28 and a new one has to be used. The core functionality of the view is now implemented in our stand-alone class, not inheriting any core interface. It is then just wrapped differently depending on the cloud version used. What doesn't currently work on NC28, is starting playback of a new list by clicking a song name in the playlist tab view. This still works on the older clouds, though. --- js/embedded/embeddedplayer.js | 2 +- js/embedded/playlisttabview.js | 202 +++++++++++++++++++-------------- 2 files changed, 117 insertions(+), 87 deletions(-) diff --git a/js/embedded/embeddedplayer.js b/js/embedded/embeddedplayer.js index 9673f5a35..40841d7a1 100644 --- a/js/embedded/embeddedplayer.js +++ b/js/embedded/embeddedplayer.js @@ -120,7 +120,7 @@ OCA.Music.EmbeddedPlayer = function(onClose, onNext, onPrev, onMenuOpen, onShowL playlistNumberText = $(document.createElement('span')); area.append(playlistNumberText); - if (typeof OCA.Music.PlaylistTabView != 'undefined') { + if (typeof OCA.Music.playlistTabView != 'undefined') { let menuContainer = $(document.createElement('div')).attr('id', 'menu-container'); // "more" button which toggles the popup menu open/closed menuContainer.append($(document.createElement('button')) diff --git a/js/embedded/playlisttabview.js b/js/embedded/playlisttabview.js index 721d7ad76..47e2e9173 100644 --- a/js/embedded/playlisttabview.js +++ b/js/embedded/playlisttabview.js @@ -11,104 +11,134 @@ OCA.Music = OCA.Music || {}; OCA.Music.initPlaylistTabView = function(playlistMimes) { - if (typeof OCA.Files.DetailTabView != 'undefined') { - OCA.Music.PlaylistTabView = OCA.Files.DetailTabView.extend({ - id: 'musicPlaylistTabView', - className: 'tab musicPlaylistTabView', - - getLabel: function() { - return t('music', 'Playlist'); - }, - - getIcon: function() { - return 'icon-music'; - }, - - render: function() { - let container = this.$el; - container.empty(); // erase any previous content - - let fileInfo = this.getFileInfo(); - - if (fileInfo) { - - let loadIndicator = $(document.createElement('div')).attr('class', 'loading'); - container.append(loadIndicator); - let onPlaylistLoaded = (data) => { - loadIndicator.hide(); + class PlaylistTabView { + id = 'musicPlaylistTabView'; + name = t('music', 'Playlist'); + icon = 'icon-music'; + $el = null; + fileInfo = null; - let list = $(document.createElement('ol')); - container.append(list); - - let titleForFile = function(file) { - return file.caption || OCA.Music.Utils.titleFromFilename(file.name); - }; - - let tooltipForFile = function(file) { - return file.path ? `${file.path}/${file.name}` : file.url; - }; - - for (let i = 0; i < data.files.length; ++i) { - list.append($(document.createElement('li')) - .attr('id', 'music-playlist-item-' + i) - .text(titleForFile(data.files[i])) - .prop('title', tooltipForFile(data.files[i]))); - } - - // click handler - list.on('click', 'li', (event) => { - let id = event.target.id; - let idx = parseInt(id.split('-').pop()); - this.trigger('playlistItemClick', fileInfo.id, fileInfo.attributes.name, idx); - }); - - if (data.invalid_paths.length > 0) { - container.append($(document.createElement('p')).text(t('music', 'Some files on the playlist were not found') + ':')); - let failList = $(document.createElement('ul')); - container.append(failList); - - for (let i = 0; i < data.invalid_paths.length; ++i) { - failList.append($(document.createElement('li')).text(data.invalid_paths[i])); - } - } - - this.trigger('rendered'); + enabled(fileInfo) { + if (!fileInfo || fileInfo.isDirectory()) { + return false; + } + const mimetype = fileInfo.get('mimetype'); + return (mimetype && playlistMimes.indexOf(mimetype) > -1); + } + + populate(fileInfo) { + this.$el.empty(); // erase any previous content + this.fileInfo = fileInfo; + + if (fileInfo) { + + let loadIndicator = $(document.createElement('div')).attr('class', 'loading'); + this.$el.append(loadIndicator); + + let onPlaylistLoaded = (data) => { + loadIndicator.hide(); + + let list = $(document.createElement('ol')); + this.$el.append(list); + + let titleForFile = function(file) { + return file.caption || OCA.Music.Utils.titleFromFilename(file.name); }; - - let onError = function(_error) { - loadIndicator.hide(); - container.append($(document.createElement('p')).text(t('music', 'Error reading playlist file'))); + + let tooltipForFile = function(file) { + return file.path ? `${file.path}/${file.name}` : file.url; }; + + for (let i = 0; i < data.files.length; ++i) { + list.append($(document.createElement('li')) + .attr('id', 'music-playlist-item-' + i) + .text(titleForFile(data.files[i])) + .prop('title', tooltipForFile(data.files[i]))); + } + + // click handler + list.on('click', 'li', (event) => { + let id = event.target.id; + let idx = parseInt(id.split('-').pop()); + this.trigger('playlistItemClick', fileInfo.id, fileInfo.attributes?.name ?? fileInfo.name, idx); + }); + + if (data.invalid_paths.length > 0) { + this.$el.append($(document.createElement('p')).text(t('music', 'Some files on the playlist were not found') + ':')); + let failList = $(document.createElement('ul')); + this.$el.append(failList); + + for (let i = 0; i < data.invalid_paths.length; ++i) { + failList.append($(document.createElement('li')).text(data.invalid_paths[i])); + } + } + + this.trigger('rendered'); + }; + + let onError = function(_error) { + loadIndicator.hide(); + this.$el.append($(document.createElement('p')).text(t('music', 'Error reading playlist file'))); + }; + + OCA.Music.PlaylistFileService.readFile(fileInfo.id, onPlaylistLoaded, onError); + } + } - OCA.Music.PlaylistFileService.readFile(fileInfo.id, onPlaylistLoaded, onError); - } - }, - - canDisplay: function(fileInfo) { - if (!fileInfo || fileInfo.isDirectory()) { - return false; - } - let mimetype = fileInfo.get('mimetype'); + setCurrentTrack(playlistId, trackIndex) { + this.$el.find('ol li.current').removeClass('current'); + if (this.fileInfo && this.fileInfo.id == playlistId) { + this.$el.find('ol li#music-playlist-item-' + trackIndex).addClass('current'); + } + } + } + _.extend(PlaylistTabView.prototype, OC.Backbone.Events); - return (mimetype && playlistMimes.indexOf(mimetype) > -1); - }, + // Registration before NC28 + if (OCA.Files?.DetailTabView) { + OCA.Music.playlistTabView = new PlaylistTabView(); - setCurrentTrack: function(playlistId, trackIndex) { - this.$el.find('ol li.current').removeClass('current'); - let fileInfo = this.getFileInfo(); - if (fileInfo && fileInfo.id == playlistId) { - this.$el.find('ol li#music-playlist-item-' + trackIndex).addClass('current'); - } + const WrappedPlaylistTabView = OCA.Files.DetailTabView.extend({ + id: OCA.Music.playlistTabView.id, + className: 'tab musicPlaylistTabView', + getLabel: () => OCA.Music.playlistTabView.name, + getIcon: () => OCA.Music.playlistTabView.icon, + canDisplay: OCA.Music.playlistTabView.enabled, + render: function() { + OCA.Music.playlistTabView.$el = this.$el; + OCA.Music.playlistTabView.populate(this.getFileInfo()); } }); - _.extend(OCA.Music.PlaylistTabView.prototype, OC.Backbone.Events); - OCA.Music.playlistTabView = new OCA.Music.PlaylistTabView(); - OC.Plugins.register('OCA.Files.FileList', { attach: function(fileList) { - fileList.registerTabView(OCA.Music.playlistTabView); + fileList.registerTabView(new WrappedPlaylistTabView()); } }); } + + // Registration after NC28 + else if (OCA.Files?.Sidebar) { + OCA.Music.playlistTabView = new PlaylistTabView(); + + OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab({ + id: OCA.Music.playlistTabView.id, + name: OCA.Music.playlistTabView.name, + icon: OCA.Music.playlistTabView.icon, + + async mount(el, fileInfo, _context) { + OCA.Music.playlistTabView.$el = $(el); + OCA.Music.playlistTabView.$el.addClass('musicPlaylistTabView'); + OCA.Music.playlistTabView.populate(fileInfo); + }, + update(fileInfo) { + OCA.Music.playlistTabView.populate(fileInfo); + }, + destroy() { + }, + enabled(fileInfo) { + return OCA.Music.playlistTabView.enabled(fileInfo); + }, + })); + } };