retold-remote 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/css/retold-remote.css +3 -0
- package/html/index.html +1 -1
- package/package.json +1 -1
- package/source/Pict-Application-RetoldRemote.js +21 -2
- package/source/cli/RetoldRemote-Server-Setup.js +129 -0
- package/source/providers/Pict-Provider-AISortManager.js +456 -0
- package/source/providers/Pict-Provider-CollectionManager.js +266 -0
- package/source/server/RetoldRemote-AISortService.js +879 -0
- package/source/server/RetoldRemote-CollectionService.js +161 -2
- package/source/server/RetoldRemote-FileOperationService.js +560 -0
- package/source/server/RetoldRemote-MediaService.js +12 -0
- package/source/server/RetoldRemote-MetadataCache.js +411 -0
- package/source/views/PictView-Remote-CollectionsPanel.js +435 -36
- package/source/views/PictView-Remote-Layout.js +2 -0
- package/source/views/PictView-Remote-SettingsPanel.js +156 -0
- package/source/views/PictView-Remote-TopBar.js +86 -0
- package/web-application/css/retold-remote.css +3 -0
- package/web-application/index.html +1 -1
- package/web-application/retold-remote.js +402 -34
- package/web-application/retold-remote.js.map +1 -1
- package/web-application/retold-remote.min.js +32 -15
- package/web-application/retold-remote.min.js.map +1 -1
|
@@ -9046,7 +9046,7 @@ if(psychotic){result.hostname=isAbsolute?'':srcPath.length?srcPath.shift():'';re
|
|
|
9046
9046
|
* url.resolveObject('mailto:local1@domain1', 'local2@domain2')
|
|
9047
9047
|
*/var authInHost=result.host&&result.host.indexOf('@')>0?result.host.split('@'):false;if(authInHost){result.auth=authInHost.shift();result.hostname=authInHost.shift();result.host=result.hostname;}}mustEndAbs=mustEndAbs||result.host&&srcPath.length;if(mustEndAbs&&!isAbsolute){srcPath.unshift('');}if(srcPath.length>0){result.pathname=srcPath.join('/');}else{result.pathname=null;result.path=null;}// to support request.http
|
|
9048
9048
|
if(result.pathname!==null||result.search!==null){result.path=(result.pathname?result.pathname:'')+(result.search?result.search:'');}result.auth=relative.auth||result.auth;result.slashes=result.slashes||relative.slashes;result.href=result.format();return result;};Url.prototype.parseHost=function(){var host=this.host;var port=portPattern.exec(host);if(port){port=port[0];if(port!==':'){this.port=port.substr(1);}host=host.substr(0,host.length-port.length);}if(host){this.hostname=host;}};exports.parse=urlParse;exports.resolve=urlResolve;exports.resolveObject=urlResolveObject;exports.format=urlFormat;exports.Url=Url;},{"punycode/":78,"qs":80}],111:[function(require,module,exports){module.exports={"Name":"Retold Remote","MainViewportViewIdentifier":"ContentEditor-Layout","AutoSolveAfterInitialize":true,"AutoRenderMainViewportViewAfterInitialize":false,"AutoRenderViewsAfterInitialize":false};},{}],112:[function(require,module,exports){const libContentEditorApplication=require('retold-content-system').PictContentEditor;const libPictSectionFileBrowser=require('pict-section-filebrowser');// Providers
|
|
9049
|
-
const libProviderRetoldRemote=require('./providers/Pict-Provider-RetoldRemote.js');const libProviderGalleryNavigation=require('./providers/Pict-Provider-GalleryNavigation.js');const libProviderGalleryFilterSort=require('./providers/Pict-Provider-GalleryFilterSort.js');const libProviderRetoldRemoteIcons=require('./providers/Pict-Provider-RetoldRemoteIcons.js');const libProviderRetoldRemoteTheme=require('./providers/Pict-Provider-RetoldRemoteTheme.js');const libProviderFormattingUtilities=require('./providers/Pict-Provider-FormattingUtilities.js');const libProviderToastNotification=require('./providers/Pict-Provider-ToastNotification.js');const libProviderCollectionManager=require('./providers/Pict-Provider-CollectionManager.js');// Views (replace parent views)
|
|
9049
|
+
const libProviderRetoldRemote=require('./providers/Pict-Provider-RetoldRemote.js');const libProviderGalleryNavigation=require('./providers/Pict-Provider-GalleryNavigation.js');const libProviderGalleryFilterSort=require('./providers/Pict-Provider-GalleryFilterSort.js');const libProviderRetoldRemoteIcons=require('./providers/Pict-Provider-RetoldRemoteIcons.js');const libProviderRetoldRemoteTheme=require('./providers/Pict-Provider-RetoldRemoteTheme.js');const libProviderFormattingUtilities=require('./providers/Pict-Provider-FormattingUtilities.js');const libProviderToastNotification=require('./providers/Pict-Provider-ToastNotification.js');const libProviderCollectionManager=require('./providers/Pict-Provider-CollectionManager.js');const libProviderAISortManager=require('./providers/Pict-Provider-AISortManager.js');// Views (replace parent views)
|
|
9050
9050
|
const libViewLayout=require('./views/PictView-Remote-Layout.js');const libViewTopBar=require('./views/PictView-Remote-TopBar.js');const libViewSettingsPanel=require('./views/PictView-Remote-SettingsPanel.js');// Views (new)
|
|
9051
9051
|
const libViewGallery=require('./views/PictView-Remote-Gallery.js');const libViewMediaViewer=require('./views/PictView-Remote-MediaViewer.js');const libViewImageViewer=require('./views/PictView-Remote-ImageViewer.js');const libViewVideoExplorer=require('./views/PictView-Remote-VideoExplorer.js');const libViewAudioExplorer=require('./views/PictView-Remote-AudioExplorer.js');const libViewVLCSetup=require('./views/PictView-Remote-VLCSetup.js');const libViewCollectionsPanel=require('./views/PictView-Remote-CollectionsPanel.js');// Application configuration
|
|
9052
9052
|
const _DefaultConfiguration=require('./Pict-Application-RetoldRemote-Configuration.json');/**
|
|
@@ -9060,7 +9060,7 @@ const _DefaultConfiguration=require('./Pict-Application-RetoldRemote-Configurati
|
|
|
9060
9060
|
// Re-registering with the same ViewIdentifier replaces the parent's view.
|
|
9061
9061
|
this.pict.addView('ContentEditor-Layout',libViewLayout.default_configuration,libViewLayout);this.pict.addView('ContentEditor-TopBar',libViewTopBar.default_configuration,libViewTopBar);// Add new views
|
|
9062
9062
|
this.pict.addView('RetoldRemote-Gallery',libViewGallery.default_configuration,libViewGallery);this.pict.addView('RetoldRemote-MediaViewer',libViewMediaViewer.default_configuration,libViewMediaViewer);this.pict.addView('RetoldRemote-ImageViewer',libViewImageViewer.default_configuration,libViewImageViewer);this.pict.addView('RetoldRemote-SettingsPanel',libViewSettingsPanel.default_configuration,libViewSettingsPanel);this.pict.addView('RetoldRemote-VideoExplorer',libViewVideoExplorer.default_configuration,libViewVideoExplorer);this.pict.addView('RetoldRemote-AudioExplorer',libViewAudioExplorer.default_configuration,libViewAudioExplorer);this.pict.addView('RetoldRemote-VLCSetup',libViewVLCSetup.default_configuration,libViewVLCSetup);this.pict.addView('RetoldRemote-CollectionsPanel',libViewCollectionsPanel.default_configuration,libViewCollectionsPanel);// Add new providers
|
|
9063
|
-
this.pict.addProvider('RetoldRemote-Provider',libProviderRetoldRemote.default_configuration,libProviderRetoldRemote);this.pict.addProvider('RetoldRemote-GalleryNavigation',libProviderGalleryNavigation.default_configuration,libProviderGalleryNavigation);this.pict.addProvider('RetoldRemote-GalleryFilterSort',libProviderGalleryFilterSort.default_configuration,libProviderGalleryFilterSort);this.pict.addProvider('RetoldRemote-Icons',libProviderRetoldRemoteIcons.default_configuration,libProviderRetoldRemoteIcons);this.pict.addProvider('RetoldRemote-Theme',libProviderRetoldRemoteTheme.default_configuration,libProviderRetoldRemoteTheme);this.pict.addProvider('RetoldRemote-FormattingUtilities',libProviderFormattingUtilities.default_configuration,libProviderFormattingUtilities);this.pict.addProvider('RetoldRemote-ToastNotification',libProviderToastNotification.default_configuration,libProviderToastNotification);this.pict.addProvider('RetoldRemote-CollectionManager',libProviderCollectionManager.default_configuration,libProviderCollectionManager);}onAfterInitializeAsync(fCallback){// Expose pict on window for inline onclick handlers
|
|
9063
|
+
this.pict.addProvider('RetoldRemote-Provider',libProviderRetoldRemote.default_configuration,libProviderRetoldRemote);this.pict.addProvider('RetoldRemote-GalleryNavigation',libProviderGalleryNavigation.default_configuration,libProviderGalleryNavigation);this.pict.addProvider('RetoldRemote-GalleryFilterSort',libProviderGalleryFilterSort.default_configuration,libProviderGalleryFilterSort);this.pict.addProvider('RetoldRemote-Icons',libProviderRetoldRemoteIcons.default_configuration,libProviderRetoldRemoteIcons);this.pict.addProvider('RetoldRemote-Theme',libProviderRetoldRemoteTheme.default_configuration,libProviderRetoldRemoteTheme);this.pict.addProvider('RetoldRemote-FormattingUtilities',libProviderFormattingUtilities.default_configuration,libProviderFormattingUtilities);this.pict.addProvider('RetoldRemote-ToastNotification',libProviderToastNotification.default_configuration,libProviderToastNotification);this.pict.addProvider('RetoldRemote-CollectionManager',libProviderCollectionManager.default_configuration,libProviderCollectionManager);this.pict.addProvider('RetoldRemote-AISortManager',libProviderAISortManager.default_configuration,libProviderAISortManager);}onAfterInitializeAsync(fCallback){// Expose pict on window for inline onclick handlers
|
|
9064
9064
|
if(typeof window!=='undefined'){window.pict=this.pict;}// Initialize RetoldRemote-specific state
|
|
9065
9065
|
this.pict.AppData.RetoldRemote={ActiveMode:'gallery',// 'gallery' or 'viewer'
|
|
9066
9066
|
Theme:'twilight',// Theme key (e.g. 'twilight', 'neo-tokyo')
|
|
@@ -9091,8 +9091,9 @@ FilterPresets:[],// [{ Name, FilterState, SortField, SortDirection }]
|
|
|
9091
9091
|
Collections:[],// Array of collection summaries
|
|
9092
9092
|
CollectionsPanelOpen:false,CollectionsPanelWidth:300,CollectionsPanelMode:'list',// 'list' | 'detail' | 'edit'
|
|
9093
9093
|
ActiveCollectionGUID:null,ActiveCollection:null,CollectionSearchQuery:'',LastUsedCollectionGUID:null,BrowsingCollection:false,// true when viewer is navigating collection items
|
|
9094
|
-
BrowsingCollectionIndex:-1
|
|
9095
|
-
|
|
9094
|
+
BrowsingCollectionIndex:-1,// index into ActiveCollection.Items
|
|
9095
|
+
// AI Sort settings
|
|
9096
|
+
AISortSettings:{AIEndpoint:'http://localhost:11434',AIModel:'llama3.1',AIProvider:'ollama',NamingTemplate:'{artist}/{album}/{track} - {title}'}};// Load persisted settings
|
|
9096
9097
|
this._loadRemoteSettings();// Apply the loaded theme (must happen after _loadRemoteSettings sets Theme)
|
|
9097
9098
|
let tmpThemeProvider=this.pict.providers['RetoldRemote-Theme'];if(tmpThemeProvider){tmpThemeProvider.applyTheme(this.pict.AppData.RetoldRemote.Theme);}// Initialize parent state (ContentEditor AppData)
|
|
9098
9099
|
this.pict.AppData.ContentEditor={CurrentFile:'',ActiveEditor:'markdown',IsDirty:false,IsSaving:false,IsLoading:false,Files:[],Document:{Segments:[{Content:''}]},CodeContent:'',SaveStatus:'',SaveStatusClass:'',AutoSegmentMarkdown:false,AutoSegmentDepth:1,AutoContentPreview:false,MarkdownEditingControls:true,MarkdownWordWrap:true,CodeWordWrap:false,SidebarCollapsed:this.pict.AppData.RetoldRemote.SidebarCollapsed,SidebarWidth:this.pict.AppData.RetoldRemote.SidebarWidth,AutoPreviewImages:true,AutoPreviewVideo:false,AutoPreviewAudio:false,ShowHiddenFiles:this.pict.AppData.RetoldRemote.ShowHiddenFiles,TopicsFilePath:''};// Render the layout shell
|
|
@@ -9158,11 +9159,11 @@ let tmpFilePath=tmpFragProvider?tmpFragProvider.resolveFragmentIdentifier(tmpRaw
|
|
|
9158
9159
|
let tmpExisting=tmpDetailRows.parentElement.querySelector('.retold-remote-sidebar-addfolder');if(tmpExisting){tmpExisting.parentElement.removeChild(tmpExisting);}let tmpBtn=document.createElement('button');tmpBtn.className='retold-remote-sidebar-addfolder';tmpBtn.textContent='+ New Folder';tmpBtn.title='Create a new folder here';tmpBtn.onclick=function(){pict.PictApplication.promptNewFolder();};// Insert after the detail rows container
|
|
9159
9160
|
tmpDetailRows.parentElement.appendChild(tmpBtn);}/**
|
|
9160
9161
|
* Save RetoldRemote settings to localStorage.
|
|
9161
|
-
*/saveSettings(){try{let tmpRemote=this.pict.AppData.RetoldRemote;let tmpSettings={Theme:tmpRemote.Theme,ViewMode:tmpRemote.ViewMode,ThumbnailSize:tmpRemote.ThumbnailSize,GalleryFilter:tmpRemote.GalleryFilter,ShowHiddenFiles:tmpRemote.ShowHiddenFiles,DistractionFreeShowNav:tmpRemote.DistractionFreeShowNav,ImageFitMode:tmpRemote.ImageFitMode,SidebarCollapsed:tmpRemote.SidebarCollapsed,SidebarWidth:tmpRemote.SidebarWidth,SortField:tmpRemote.SortField,SortDirection:tmpRemote.SortDirection,FilterPresets:tmpRemote.FilterPresets,FilterPanelOpen:tmpRemote.FilterPanelOpen,AutoplayVideo:tmpRemote.AutoplayVideo,AutoplayAudio:tmpRemote.AutoplayAudio,ListShowExtension:tmpRemote.ListShowExtension,ListShowSize:tmpRemote.ListShowSize,ListShowDate:tmpRemote.ListShowDate,CollectionsPanelOpen:tmpRemote.CollectionsPanelOpen,CollectionsPanelWidth:tmpRemote.CollectionsPanelWidth,LastUsedCollectionGUID:tmpRemote.LastUsedCollectionGUID};localStorage.setItem('retold-remote-settings',JSON.stringify(tmpSettings));}catch(pError){// localStorage may not be available
|
|
9162
|
+
*/saveSettings(){try{let tmpRemote=this.pict.AppData.RetoldRemote;let tmpSettings={Theme:tmpRemote.Theme,ViewMode:tmpRemote.ViewMode,ThumbnailSize:tmpRemote.ThumbnailSize,GalleryFilter:tmpRemote.GalleryFilter,ShowHiddenFiles:tmpRemote.ShowHiddenFiles,DistractionFreeShowNav:tmpRemote.DistractionFreeShowNav,ImageFitMode:tmpRemote.ImageFitMode,SidebarCollapsed:tmpRemote.SidebarCollapsed,SidebarWidth:tmpRemote.SidebarWidth,SortField:tmpRemote.SortField,SortDirection:tmpRemote.SortDirection,FilterPresets:tmpRemote.FilterPresets,FilterPanelOpen:tmpRemote.FilterPanelOpen,AutoplayVideo:tmpRemote.AutoplayVideo,AutoplayAudio:tmpRemote.AutoplayAudio,ListShowExtension:tmpRemote.ListShowExtension,ListShowSize:tmpRemote.ListShowSize,ListShowDate:tmpRemote.ListShowDate,CollectionsPanelOpen:tmpRemote.CollectionsPanelOpen,CollectionsPanelWidth:tmpRemote.CollectionsPanelWidth,LastUsedCollectionGUID:tmpRemote.LastUsedCollectionGUID,AISortSettings:tmpRemote.AISortSettings};localStorage.setItem('retold-remote-settings',JSON.stringify(tmpSettings));}catch(pError){// localStorage may not be available
|
|
9162
9163
|
}}/**
|
|
9163
9164
|
* Load RetoldRemote settings from localStorage.
|
|
9164
|
-
*/_loadRemoteSettings(){try{let tmpStored=localStorage.getItem('retold-remote-settings');if(tmpStored){let tmpSettings=JSON.parse(tmpStored);let tmpRemote=this.pict.AppData.RetoldRemote;if(tmpSettings.Theme)tmpRemote.Theme=tmpSettings.Theme;if(tmpSettings.ViewMode)tmpRemote.ViewMode=tmpSettings.ViewMode;if(tmpSettings.ThumbnailSize)tmpRemote.ThumbnailSize=tmpSettings.ThumbnailSize;if(tmpSettings.GalleryFilter){tmpRemote.GalleryFilter=tmpSettings.GalleryFilter;tmpRemote.FilterState.MediaType=tmpSettings.GalleryFilter;}if(typeof tmpSettings.ShowHiddenFiles==='boolean')tmpRemote.ShowHiddenFiles=tmpSettings.ShowHiddenFiles;if(typeof tmpSettings.DistractionFreeShowNav==='boolean')tmpRemote.DistractionFreeShowNav=tmpSettings.DistractionFreeShowNav;if(tmpSettings.ImageFitMode)tmpRemote.ImageFitMode=tmpSettings.ImageFitMode;if(typeof tmpSettings.SidebarCollapsed==='boolean')tmpRemote.SidebarCollapsed=tmpSettings.SidebarCollapsed;if(tmpSettings.SidebarWidth)tmpRemote.SidebarWidth=tmpSettings.SidebarWidth;if(tmpSettings.SortField)tmpRemote.SortField=tmpSettings.SortField;if(tmpSettings.SortDirection)tmpRemote.SortDirection=tmpSettings.SortDirection;if(Array.isArray(tmpSettings.FilterPresets))tmpRemote.FilterPresets=tmpSettings.FilterPresets;if(typeof tmpSettings.FilterPanelOpen==='boolean')tmpRemote.FilterPanelOpen=tmpSettings.FilterPanelOpen;if(typeof tmpSettings.AutoplayVideo==='boolean')tmpRemote.AutoplayVideo=tmpSettings.AutoplayVideo;if(typeof tmpSettings.AutoplayAudio==='boolean')tmpRemote.AutoplayAudio=tmpSettings.AutoplayAudio;if(typeof tmpSettings.ListShowExtension==='boolean')tmpRemote.ListShowExtension=tmpSettings.ListShowExtension;if(typeof tmpSettings.ListShowSize==='boolean')tmpRemote.ListShowSize=tmpSettings.ListShowSize;if(typeof tmpSettings.ListShowDate==='boolean')tmpRemote.ListShowDate=tmpSettings.ListShowDate;if(typeof tmpSettings.CollectionsPanelOpen==='boolean')tmpRemote.CollectionsPanelOpen=tmpSettings.CollectionsPanelOpen;if(tmpSettings.CollectionsPanelWidth)tmpRemote.CollectionsPanelWidth=tmpSettings.CollectionsPanelWidth;if(tmpSettings.LastUsedCollectionGUID)tmpRemote.LastUsedCollectionGUID=tmpSettings.LastUsedCollectionGUID;}}catch(pError){// localStorage may not be available
|
|
9165
|
-
}}}module.exports=RetoldRemoteApplication;},{"./Pict-Application-RetoldRemote-Configuration.json":111,"./providers/Pict-Provider-
|
|
9165
|
+
*/_loadRemoteSettings(){try{let tmpStored=localStorage.getItem('retold-remote-settings');if(tmpStored){let tmpSettings=JSON.parse(tmpStored);let tmpRemote=this.pict.AppData.RetoldRemote;if(tmpSettings.Theme)tmpRemote.Theme=tmpSettings.Theme;if(tmpSettings.ViewMode)tmpRemote.ViewMode=tmpSettings.ViewMode;if(tmpSettings.ThumbnailSize)tmpRemote.ThumbnailSize=tmpSettings.ThumbnailSize;if(tmpSettings.GalleryFilter){tmpRemote.GalleryFilter=tmpSettings.GalleryFilter;tmpRemote.FilterState.MediaType=tmpSettings.GalleryFilter;}if(typeof tmpSettings.ShowHiddenFiles==='boolean')tmpRemote.ShowHiddenFiles=tmpSettings.ShowHiddenFiles;if(typeof tmpSettings.DistractionFreeShowNav==='boolean')tmpRemote.DistractionFreeShowNav=tmpSettings.DistractionFreeShowNav;if(tmpSettings.ImageFitMode)tmpRemote.ImageFitMode=tmpSettings.ImageFitMode;if(typeof tmpSettings.SidebarCollapsed==='boolean')tmpRemote.SidebarCollapsed=tmpSettings.SidebarCollapsed;if(tmpSettings.SidebarWidth)tmpRemote.SidebarWidth=tmpSettings.SidebarWidth;if(tmpSettings.SortField)tmpRemote.SortField=tmpSettings.SortField;if(tmpSettings.SortDirection)tmpRemote.SortDirection=tmpSettings.SortDirection;if(Array.isArray(tmpSettings.FilterPresets))tmpRemote.FilterPresets=tmpSettings.FilterPresets;if(typeof tmpSettings.FilterPanelOpen==='boolean')tmpRemote.FilterPanelOpen=tmpSettings.FilterPanelOpen;if(typeof tmpSettings.AutoplayVideo==='boolean')tmpRemote.AutoplayVideo=tmpSettings.AutoplayVideo;if(typeof tmpSettings.AutoplayAudio==='boolean')tmpRemote.AutoplayAudio=tmpSettings.AutoplayAudio;if(typeof tmpSettings.ListShowExtension==='boolean')tmpRemote.ListShowExtension=tmpSettings.ListShowExtension;if(typeof tmpSettings.ListShowSize==='boolean')tmpRemote.ListShowSize=tmpSettings.ListShowSize;if(typeof tmpSettings.ListShowDate==='boolean')tmpRemote.ListShowDate=tmpSettings.ListShowDate;if(typeof tmpSettings.CollectionsPanelOpen==='boolean')tmpRemote.CollectionsPanelOpen=tmpSettings.CollectionsPanelOpen;if(tmpSettings.CollectionsPanelWidth)tmpRemote.CollectionsPanelWidth=tmpSettings.CollectionsPanelWidth;if(tmpSettings.LastUsedCollectionGUID)tmpRemote.LastUsedCollectionGUID=tmpSettings.LastUsedCollectionGUID;if(tmpSettings.AISortSettings&&typeof tmpSettings.AISortSettings==='object'){if(tmpSettings.AISortSettings.AIEndpoint)tmpRemote.AISortSettings.AIEndpoint=tmpSettings.AISortSettings.AIEndpoint;if(tmpSettings.AISortSettings.AIModel)tmpRemote.AISortSettings.AIModel=tmpSettings.AISortSettings.AIModel;if(tmpSettings.AISortSettings.AIProvider)tmpRemote.AISortSettings.AIProvider=tmpSettings.AISortSettings.AIProvider;if(tmpSettings.AISortSettings.NamingTemplate)tmpRemote.AISortSettings.NamingTemplate=tmpSettings.AISortSettings.NamingTemplate;}}}catch(pError){// localStorage may not be available
|
|
9166
|
+
}}}module.exports=RetoldRemoteApplication;},{"./Pict-Application-RetoldRemote-Configuration.json":111,"./providers/Pict-Provider-AISortManager.js":115,"./providers/Pict-Provider-CollectionManager.js":116,"./providers/Pict-Provider-FormattingUtilities.js":117,"./providers/Pict-Provider-GalleryFilterSort.js":118,"./providers/Pict-Provider-GalleryNavigation.js":119,"./providers/Pict-Provider-RetoldRemote.js":120,"./providers/Pict-Provider-RetoldRemoteIcons.js":121,"./providers/Pict-Provider-RetoldRemoteTheme.js":122,"./providers/Pict-Provider-ToastNotification.js":123,"./views/PictView-Remote-AudioExplorer.js":129,"./views/PictView-Remote-CollectionsPanel.js":130,"./views/PictView-Remote-Gallery.js":131,"./views/PictView-Remote-ImageViewer.js":132,"./views/PictView-Remote-Layout.js":133,"./views/PictView-Remote-MediaViewer.js":134,"./views/PictView-Remote-SettingsPanel.js":135,"./views/PictView-Remote-TopBar.js":136,"./views/PictView-Remote-VLCSetup.js":137,"./views/PictView-Remote-VideoExplorer.js":138,"pict-section-filebrowser":54,"retold-content-system":97}],113:[function(require,module,exports){/**
|
|
9166
9167
|
* Retold Remote -- Browser Bundle Entry
|
|
9167
9168
|
*
|
|
9168
9169
|
* Exports the RetoldRemote application class for browser consumption.
|
|
@@ -9177,6 +9178,78 @@ tmpDetailRows.parentElement.appendChild(tmpBtn);}/**
|
|
|
9177
9178
|
* @param {string} pExtension - Extension with or without leading dot (e.g. '.png' or 'png')
|
|
9178
9179
|
* @returns {string} 'image', 'video', 'audio', 'document', or 'other'
|
|
9179
9180
|
*/function getCategory(pExtension){let tmpExt=(pExtension||'').replace(/^\./,'').toLowerCase();if(ImageExtensions[tmpExt])return'image';if(VideoExtensions[tmpExt])return'video';if(AudioExtensions[tmpExt])return'audio';if(DocumentExtensions[tmpExt])return'document';return'other';}module.exports.ImageExtensions=ImageExtensions;module.exports.VideoExtensions=VideoExtensions;module.exports.AudioExtensions=AudioExtensions;module.exports.DocumentExtensions=DocumentExtensions;module.exports.getCategory=getCategory;},{}],115:[function(require,module,exports){/**
|
|
9181
|
+
* Retold Remote -- AI Sort Manager Provider
|
|
9182
|
+
*
|
|
9183
|
+
* Client-side state management and API communication for the
|
|
9184
|
+
* AI-powered file sorting feature. Manages AI endpoint settings,
|
|
9185
|
+
* connection testing, folder scanning, and sort plan generation.
|
|
9186
|
+
*
|
|
9187
|
+
* Sort plans are created as operation-plan collections, so all
|
|
9188
|
+
* preview, editing, and execution happens through the existing
|
|
9189
|
+
* collections infrastructure.
|
|
9190
|
+
*
|
|
9191
|
+
* Settings are persisted via localStorage alongside other RetoldRemote
|
|
9192
|
+
* settings.
|
|
9193
|
+
*
|
|
9194
|
+
* @license MIT
|
|
9195
|
+
*/const libPictProvider=require('pict-provider');const _DefaultProviderConfiguration={ProviderIdentifier:'RetoldRemote-AISortManager',AutoInitialize:true,AutoSolveWithApp:false};class AISortManagerProvider extends libPictProvider{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);// Track in-progress operations
|
|
9196
|
+
this._generating=false;this._scanning=false;this._testingConnection=false;}// -- State Accessors --------------------------------------------------
|
|
9197
|
+
/**
|
|
9198
|
+
* Shortcut to the RetoldRemote AppData namespace.
|
|
9199
|
+
*/_getRemote(){return this.pict.AppData.RetoldRemote;}/**
|
|
9200
|
+
* Get the AI sort settings from AppData.
|
|
9201
|
+
*/_getSettings(){let tmpRemote=this._getRemote();if(!tmpRemote.AISortSettings){tmpRemote.AISortSettings={AIEndpoint:'http://localhost:11434',AIModel:'llama3.1',AIProvider:'ollama',NamingTemplate:'{artist}/{album}/{track} - {title}'};}return tmpRemote.AISortSettings;}/**
|
|
9202
|
+
* Get the toast notification provider.
|
|
9203
|
+
*/_getToast(){return this.pict.providers['RetoldRemote-ToastNotification'];}/**
|
|
9204
|
+
* Get the collection manager provider.
|
|
9205
|
+
*/_getCollectionManager(){return this.pict.providers['RetoldRemote-CollectionManager'];}// -- Settings Management ----------------------------------------------
|
|
9206
|
+
/**
|
|
9207
|
+
* Update AI sort settings.
|
|
9208
|
+
*
|
|
9209
|
+
* @param {object} pSettings - Settings object with any of: AIEndpoint, AIModel, AIProvider, NamingTemplate
|
|
9210
|
+
*/updateSettings(pSettings){let tmpSettings=this._getSettings();if(pSettings.AIEndpoint!==undefined){tmpSettings.AIEndpoint=pSettings.AIEndpoint;}if(pSettings.AIModel!==undefined){tmpSettings.AIModel=pSettings.AIModel;}if(pSettings.AIProvider!==undefined){tmpSettings.AIProvider=pSettings.AIProvider;}if(pSettings.NamingTemplate!==undefined){tmpSettings.NamingTemplate=pSettings.NamingTemplate;}// Persist settings
|
|
9211
|
+
this.pict.PictApplication.saveSettings();}// -- API Methods ------------------------------------------------------
|
|
9212
|
+
/**
|
|
9213
|
+
* Test the AI endpoint connection.
|
|
9214
|
+
*
|
|
9215
|
+
* @param {Function} [fCallback] - Optional callback(pError, pResult)
|
|
9216
|
+
*/testConnection(fCallback){let tmpSelf=this;let tmpCallback=typeof fCallback==='function'?fCallback:()=>{};if(this._testingConnection){return tmpCallback(new Error('Connection test already in progress'));}this._testingConnection=true;let tmpSettings=this._getSettings();let tmpToast=this._getToast();fetch('/api/ai-sort/test-connection',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({AIEndpoint:tmpSettings.AIEndpoint,AIModel:tmpSettings.AIModel,AIProvider:tmpSettings.AIProvider})}).then(pResponse=>pResponse.json()).then(pData=>{tmpSelf._testingConnection=false;if(pData.Success){if(tmpToast){tmpToast.show('AI connected ('+pData.ResponseTime+'ms)');}}else{if(tmpToast){tmpToast.show('AI connection failed: '+(pData.Error||'Unknown error'));}}// Update the test button state if settings panel is open
|
|
9217
|
+
tmpSelf._updateTestButtonState(pData.Success);return tmpCallback(null,pData);}).catch(pError=>{tmpSelf._testingConnection=false;if(tmpToast){tmpToast.show('AI connection error: '+pError.message);}tmpSelf._updateTestButtonState(false);return tmpCallback(pError);});}/**
|
|
9218
|
+
* Scan a folder for audio files and return metadata.
|
|
9219
|
+
*
|
|
9220
|
+
* @param {string} pPath - Folder path relative to content root
|
|
9221
|
+
* @param {boolean} [pRecursive] - Scan subdirectories
|
|
9222
|
+
* @param {Function} [fCallback] - Optional callback(pError, pResult)
|
|
9223
|
+
*/scanFolder(pPath,pRecursive,fCallback){let tmpSelf=this;let tmpCallback=typeof fCallback==='function'?fCallback:()=>{};if(this._scanning){return tmpCallback(new Error('Scan already in progress'));}this._scanning=true;fetch('/api/ai-sort/scan',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({Path:pPath||'',Recursive:pRecursive||false})}).then(pResponse=>pResponse.json()).then(pData=>{tmpSelf._scanning=false;let tmpToast=tmpSelf._getToast();if(tmpToast){if(pData.Success){tmpToast.show('Scanned '+pData.FileCount+' audio files');}else{tmpToast.show('Scan failed: '+(pData.Error||'Unknown error'));}}return tmpCallback(null,pData);}).catch(pError=>{tmpSelf._scanning=false;let tmpToast=tmpSelf._getToast();if(tmpToast){tmpToast.show('Scan error: '+pError.message);}return tmpCallback(pError);});}/**
|
|
9224
|
+
* Generate a sort plan for a folder.
|
|
9225
|
+
*
|
|
9226
|
+
* Creates an operation-plan collection and opens it in the
|
|
9227
|
+
* collections panel for preview and editing.
|
|
9228
|
+
*
|
|
9229
|
+
* @param {string} pPath - Folder path relative to content root
|
|
9230
|
+
* @param {Function} [fCallback] - Optional callback(pError, pResult)
|
|
9231
|
+
*/generateSortPlan(pPath,fCallback){let tmpSelf=this;let tmpCallback=typeof fCallback==='function'?fCallback:()=>{};if(this._generating){let tmpToast=this._getToast();if(tmpToast){tmpToast.show('Sort plan generation already in progress...');}return tmpCallback(new Error('Generation already in progress'));}this._generating=true;let tmpSettings=this._getSettings();let tmpToast=this._getToast();if(tmpToast){tmpToast.show('Generating sort plan...');}fetch('/api/ai-sort/generate-plan',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({Path:pPath||'',NamingTemplate:tmpSettings.NamingTemplate,Recursive:true,AIEndpoint:tmpSettings.AIEndpoint,AIModel:tmpSettings.AIModel,AIProvider:tmpSettings.AIProvider})}).then(pResponse=>pResponse.json()).then(pData=>{tmpSelf._generating=false;if(!pData.Success){if(tmpToast){tmpToast.show('Sort plan failed: '+(pData.Error||pData.Message||'Unknown error'));}return tmpCallback(new Error(pData.Error||pData.Message));}if(!pData.CollectionGUID){if(tmpToast){tmpToast.show(pData.Message||'No audio files found');}return tmpCallback(null,pData);}// Open the generated collection in the panel
|
|
9232
|
+
let tmpCollManager=tmpSelf._getCollectionManager();if(tmpCollManager){let tmpRemote=tmpSelf._getRemote();tmpRemote.CollectionsPanelMode='detail';if(!tmpRemote.CollectionsPanelOpen){tmpCollManager.togglePanel();}tmpCollManager.fetchCollection(pData.CollectionGUID);tmpCollManager.fetchCollections();}if(tmpToast){let tmpMsg='Sort plan created: '+pData.TotalFiles+' files';if(pData.TaggedFiles>0){tmpMsg+=' ('+pData.TaggedFiles+' by tags';if(pData.AIFiles>0){tmpMsg+=', '+pData.AIFiles+' by AI';}tmpMsg+=')';}tmpToast.show(tmpMsg);}return tmpCallback(null,pData);}).catch(pError=>{tmpSelf._generating=false;if(tmpToast){tmpToast.show('Sort plan error: '+pError.message);}return tmpCallback(pError);});}// -- UI Helpers --------------------------------------------------------
|
|
9233
|
+
/**
|
|
9234
|
+
* Update the test connection button state in the settings panel.
|
|
9235
|
+
*
|
|
9236
|
+
* @param {boolean} pSuccess - Whether the test was successful
|
|
9237
|
+
*/_updateTestButtonState(pSuccess){let tmpBtn=document.getElementById('RetoldRemote-AISortTestBtn');if(!tmpBtn){return;}tmpBtn.disabled=false;if(pSuccess===true){tmpBtn.style.borderColor='var(--retold-accent)';tmpBtn.style.color='var(--retold-accent)';tmpBtn.textContent='Connected';setTimeout(()=>{tmpBtn.textContent='Test Connection';tmpBtn.style.borderColor='';tmpBtn.style.color='';},3000);}else if(pSuccess===false){tmpBtn.style.borderColor='var(--retold-danger-muted)';tmpBtn.style.color='var(--retold-danger-muted)';tmpBtn.textContent='Failed';setTimeout(()=>{tmpBtn.textContent='Test Connection';tmpBtn.style.borderColor='';tmpBtn.style.color='';},3000);}}/**
|
|
9238
|
+
* Get a preview of the naming template with sample data.
|
|
9239
|
+
*
|
|
9240
|
+
* @param {string} pTemplate - Naming template
|
|
9241
|
+
* @returns {string} Preview string
|
|
9242
|
+
*/getTemplatePreview(pTemplate){let tmpTemplate=pTemplate||'{artist}/{album}/{track} - {title}';let tmpPreview=tmpTemplate.replace(/\{artist\}/gi,'Pink Floyd').replace(/\{album\}/gi,'Dark Side of the Moon').replace(/\{title\}/gi,'Time').replace(/\{track\}/gi,'04').replace(/\{year\}/gi,'1973').replace(/\{genre\}/gi,'Progressive Rock');return tmpPreview+'.mp3';}/**
|
|
9243
|
+
* Whether the AI sort button should be visible for the current folder.
|
|
9244
|
+
*
|
|
9245
|
+
* Returns true if we're in gallery mode (browsing a folder).
|
|
9246
|
+
*
|
|
9247
|
+
* @returns {boolean}
|
|
9248
|
+
*/isAvailable(){let tmpRemote=this._getRemote();return tmpRemote.ActiveMode==='gallery';}/**
|
|
9249
|
+
* Whether a generation is currently in progress.
|
|
9250
|
+
*
|
|
9251
|
+
* @returns {boolean}
|
|
9252
|
+
*/isGenerating(){return this._generating;}}AISortManagerProvider.default_configuration=_DefaultProviderConfiguration;module.exports=AISortManagerProvider;},{"pict-provider":46}],116:[function(require,module,exports){/**
|
|
9180
9253
|
* Retold Remote -- Collection Manager Provider
|
|
9181
9254
|
*
|
|
9182
9255
|
* Client-side state management and API communication for the
|
|
@@ -9335,7 +9408,39 @@ fetch('/api/collections/'+encodeURIComponent(tmpCollection.GUID),{method:'PUT',h
|
|
|
9335
9408
|
*
|
|
9336
9409
|
* @param {string} pQuery - Search query
|
|
9337
9410
|
* @returns {Array} Filtered collection summaries
|
|
9338
|
-
*/searchCollections(pQuery){let tmpRemote=this._getRemote();let tmpQuery=(pQuery||'').toLowerCase();if(!tmpQuery){return tmpRemote.Collections;}return tmpRemote.Collections.filter(pCollection=>{let tmpName=(pCollection.Name||'').toLowerCase();let tmpDesc=(pCollection.Description||'').toLowerCase();let tmpTags=(pCollection.Tags||[]).join(' ').toLowerCase();return tmpName.indexOf(tmpQuery)>=0||tmpDesc.indexOf(tmpQuery)>=0||tmpTags.indexOf(tmpQuery)>=0;});}
|
|
9411
|
+
*/searchCollections(pQuery){let tmpRemote=this._getRemote();let tmpQuery=(pQuery||'').toLowerCase();if(!tmpQuery){return tmpRemote.Collections;}return tmpRemote.Collections.filter(pCollection=>{let tmpName=(pCollection.Name||'').toLowerCase();let tmpDesc=(pCollection.Description||'').toLowerCase();let tmpTags=(pCollection.Tags||[]).join(' ').toLowerCase();return tmpName.indexOf(tmpQuery)>=0||tmpDesc.indexOf(tmpQuery)>=0||tmpTags.indexOf(tmpQuery)>=0;});}// -- Operation Plan Methods -------------------------------------------
|
|
9412
|
+
/**
|
|
9413
|
+
* Create an operation-plan collection with pre-populated items.
|
|
9414
|
+
*
|
|
9415
|
+
* @param {string} pName - Plan name
|
|
9416
|
+
* @param {Array} pItems - Items with Operation and DestinationPath set
|
|
9417
|
+
* @param {Function} [fCallback] - Optional callback(pError, pCollection)
|
|
9418
|
+
*/createOperationPlan(pName,pItems,fCallback){let tmpSelf=this;let tmpCallback=typeof fCallback==='function'?fCallback:()=>{};let tmpGUID=this.fable.getUUID();let tmpCollectionData={Name:pName||'Sort Plan',CollectionType:'operation-plan',Items:pItems||[]};fetch('/api/collections/'+encodeURIComponent(tmpGUID),{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify(tmpCollectionData)}).then(pResponse=>pResponse.json()).then(pData=>{let tmpRemote=tmpSelf._getRemote();// Open the panel and navigate to this collection
|
|
9419
|
+
tmpRemote.ActiveCollectionGUID=tmpGUID;tmpRemote.ActiveCollection=pData;tmpRemote.CollectionsPanelMode='detail';if(!tmpRemote.CollectionsPanelOpen){tmpSelf.togglePanel();}else{let tmpPanel=tmpSelf._getPanelView();if(tmpPanel){tmpPanel.renderContent();}}// Refresh the list
|
|
9420
|
+
tmpSelf.fetchCollections();let tmpToast=tmpSelf._getToast();if(tmpToast){tmpToast.show('Sort plan created: '+(pData.Name||pName));}return tmpCallback(null,pData);}).catch(pError=>{tmpSelf.log.error('Failed to create operation plan: '+pError.message);return tmpCallback(pError);});}/**
|
|
9421
|
+
* Execute all pending operations in a collection.
|
|
9422
|
+
*
|
|
9423
|
+
* @param {string} pGUID - Collection GUID
|
|
9424
|
+
* @param {Function} [fCallback] - Optional callback(pError, pResult)
|
|
9425
|
+
*/executeCollectionOperations(pGUID,fCallback){let tmpSelf=this;let tmpCallback=typeof fCallback==='function'?fCallback:()=>{};fetch('/api/collections/'+encodeURIComponent(pGUID)+'/execute',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({})}).then(pResponse=>pResponse.json()).then(pData=>{let tmpRemote=tmpSelf._getRemote();if(pData.Collection&&tmpRemote.ActiveCollectionGUID===pGUID){tmpRemote.ActiveCollection=pData.Collection;}let tmpPanel=tmpSelf._getPanelView();if(tmpPanel){tmpPanel.renderContent();}let tmpToast=tmpSelf._getToast();if(tmpToast){if(pData.TotalFailed>0){tmpToast.show('Moved '+pData.TotalMoved+' files ('+pData.TotalFailed+' failed)');}else{tmpToast.show('Successfully moved '+pData.TotalMoved+' files');}}return tmpCallback(null,pData);}).catch(pError=>{tmpSelf.log.error('Failed to execute operations: '+pError.message);let tmpToast=tmpSelf._getToast();if(tmpToast){tmpToast.show('Failed to execute operations: '+pError.message);}return tmpCallback(pError);});}/**
|
|
9426
|
+
* Undo the last batch of operations for a collection.
|
|
9427
|
+
*
|
|
9428
|
+
* @param {string} pGUID - Collection GUID
|
|
9429
|
+
* @param {Function} [fCallback] - Optional callback(pError, pResult)
|
|
9430
|
+
*/undoCollectionOperations(pGUID,fCallback){let tmpSelf=this;let tmpCallback=typeof fCallback==='function'?fCallback:()=>{};let tmpRemote=this._getRemote();let tmpCollection=tmpRemote.ActiveCollection;if(!tmpCollection||!tmpCollection.OperationBatchGUID){let tmpToast=tmpSelf._getToast();if(tmpToast){tmpToast.show('No batch to undo');}return tmpCallback(new Error('No batch to undo'));}fetch('/api/files/undo-batch',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({BatchGUID:tmpCollection.OperationBatchGUID})}).then(pResponse=>pResponse.json()).then(pData=>{// Reset operation statuses back to pending
|
|
9431
|
+
if(tmpCollection.Items){for(let i=0;i<tmpCollection.Items.length;i++){if(tmpCollection.Items[i].OperationStatus==='completed'){tmpCollection.Items[i].OperationStatus='pending';}}}tmpCollection.OperationBatchGUID=null;// Save updated collection
|
|
9432
|
+
tmpSelf.updateCollection(tmpCollection);let tmpPanel=tmpSelf._getPanelView();if(tmpPanel){tmpPanel.renderContent();}let tmpToast=tmpSelf._getToast();if(tmpToast){tmpToast.show('Undo complete: '+pData.TotalReversed+' files restored');}return tmpCallback(null,pData);}).catch(pError=>{tmpSelf.log.error('Failed to undo operations: '+pError.message);let tmpToast=tmpSelf._getToast();if(tmpToast){tmpToast.show('Failed to undo: '+pError.message);}return tmpCallback(pError);});}/**
|
|
9433
|
+
* Update a single item's destination path in the active collection.
|
|
9434
|
+
*
|
|
9435
|
+
* @param {string} pItemID - Item ID
|
|
9436
|
+
* @param {string} pNewDestPath - New destination path
|
|
9437
|
+
*/setItemDestination(pItemID,pNewDestPath){let tmpRemote=this._getRemote();let tmpCollection=tmpRemote.ActiveCollection;if(!tmpCollection||!tmpCollection.Items){return;}for(let i=0;i<tmpCollection.Items.length;i++){if(tmpCollection.Items[i].ID===pItemID){tmpCollection.Items[i].DestinationPath=pNewDestPath;break;}}// Save to server in background
|
|
9438
|
+
this.updateCollection(tmpCollection);}/**
|
|
9439
|
+
* Skip an item's operation (set status to 'skipped').
|
|
9440
|
+
*
|
|
9441
|
+
* @param {string} pItemID - Item ID
|
|
9442
|
+
*/skipItemOperation(pItemID){let tmpRemote=this._getRemote();let tmpCollection=tmpRemote.ActiveCollection;if(!tmpCollection||!tmpCollection.Items){return;}for(let i=0;i<tmpCollection.Items.length;i++){if(tmpCollection.Items[i].ID===pItemID){tmpCollection.Items[i].OperationStatus='skipped';break;}}let tmpPanel=this._getPanelView();if(tmpPanel){tmpPanel.renderContent();}// Save to server in background
|
|
9443
|
+
this.updateCollection(tmpCollection);}}CollectionManagerProvider.default_configuration=_DefaultProviderConfiguration;module.exports=CollectionManagerProvider;},{"pict-provider":46}],117:[function(require,module,exports){const libPictProvider=require('pict-provider');const _DefaultProviderConfiguration={ProviderIdentifier:'RetoldRemote-FormattingUtilities',AutoInitialize:true,AutoSolveWithApp:false};class FormattingUtilitiesProvider extends libPictProvider{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='RetoldRemoteProvider';}/**
|
|
9339
9444
|
* Escape HTML special characters for safe insertion into markup.
|
|
9340
9445
|
*
|
|
9341
9446
|
* @param {string} pText - Raw text to escape
|
|
@@ -9357,7 +9462,7 @@ fetch('/api/collections/'+encodeURIComponent(tmpCollection.GUID),{method:'PUT',h
|
|
|
9357
9462
|
* @param {number} pSeconds - Duration in seconds
|
|
9358
9463
|
* @param {boolean} pIncludeMilliseconds - If true, append tenths of a second
|
|
9359
9464
|
* @returns {string} Formatted string like "1:23" or "1:02:34.5"
|
|
9360
|
-
*/formatTimestamp(pSeconds,pIncludeMilliseconds){if(pSeconds===null||pSeconds===undefined||isNaN(pSeconds)){return'--';}let tmpHours=Math.floor(pSeconds/3600);let tmpMinutes=Math.floor(pSeconds%3600/60);let tmpSecs=Math.floor(pSeconds%60);let tmpResult;if(tmpHours>0){tmpResult=tmpHours+':'+String(tmpMinutes).padStart(2,'0')+':'+String(tmpSecs).padStart(2,'0');}else{tmpResult=tmpMinutes+':'+String(tmpSecs).padStart(2,'0');}if(pIncludeMilliseconds){let tmpMs=Math.floor(pSeconds%1*10);tmpResult+='.'+tmpMs;}return tmpResult;}}FormattingUtilitiesProvider.default_configuration=_DefaultProviderConfiguration;module.exports=FormattingUtilitiesProvider;},{"pict-provider":46}],
|
|
9465
|
+
*/formatTimestamp(pSeconds,pIncludeMilliseconds){if(pSeconds===null||pSeconds===undefined||isNaN(pSeconds)){return'--';}let tmpHours=Math.floor(pSeconds/3600);let tmpMinutes=Math.floor(pSeconds%3600/60);let tmpSecs=Math.floor(pSeconds%60);let tmpResult;if(tmpHours>0){tmpResult=tmpHours+':'+String(tmpMinutes).padStart(2,'0')+':'+String(tmpSecs).padStart(2,'0');}else{tmpResult=tmpMinutes+':'+String(tmpSecs).padStart(2,'0');}if(pIncludeMilliseconds){let tmpMs=Math.floor(pSeconds%1*10);tmpResult+='.'+tmpMs;}return tmpResult;}}FormattingUtilitiesProvider.default_configuration=_DefaultProviderConfiguration;module.exports=FormattingUtilitiesProvider;},{"pict-provider":46}],118:[function(require,module,exports){const libPictProvider=require('pict-provider');const libExtensionMaps=require('../RetoldRemote-ExtensionMaps.js');const _DefaultProviderConfiguration={ProviderIdentifier:'RetoldRemote-GalleryFilterSort',AutoInitialize:true,AutoInitializeOrdinal:0,AutoSolveWithApp:false};class GalleryFilterSortProvider extends libPictProvider{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);}// ──────────────────────────────────────────────
|
|
9361
9466
|
// Pipeline
|
|
9362
9467
|
// ──────────────────────────────────────────────
|
|
9363
9468
|
/**
|
|
@@ -9451,7 +9556,7 @@ if(tmpRemote.SearchQuery){let tmpSearchLabel='Search: "'+tmpRemote.SearchQuery+'
|
|
|
9451
9556
|
* Delete a saved preset.
|
|
9452
9557
|
*
|
|
9453
9558
|
* @param {number} pIndex - index into FilterPresets array
|
|
9454
|
-
*/deletePreset(pIndex){let tmpRemote=this.pict.AppData.RetoldRemote;if(!tmpRemote||!tmpRemote.FilterPresets){return;}tmpRemote.FilterPresets.splice(pIndex,1);}}GalleryFilterSortProvider.default_configuration=_DefaultProviderConfiguration;module.exports=GalleryFilterSortProvider;},{"../RetoldRemote-ExtensionMaps.js":114,"pict-provider":46}],
|
|
9559
|
+
*/deletePreset(pIndex){let tmpRemote=this.pict.AppData.RetoldRemote;if(!tmpRemote||!tmpRemote.FilterPresets){return;}tmpRemote.FilterPresets.splice(pIndex,1);}}GalleryFilterSortProvider.default_configuration=_DefaultProviderConfiguration;module.exports=GalleryFilterSortProvider;},{"../RetoldRemote-ExtensionMaps.js":114,"pict-provider":46}],119:[function(require,module,exports){const libPictProvider=require('pict-provider');const libHandleGalleryKey=require('./keyboard-handlers/KeyHandler-Gallery.js');const libHandleViewerKey=require('./keyboard-handlers/KeyHandler-Viewer.js');const libHandleSidebarKey=require('./keyboard-handlers/KeyHandler-Sidebar.js');const libHandleVideoExplorerKey=require('./keyboard-handlers/KeyHandler-VideoExplorer.js');const libHandleAudioExplorerKey=require('./keyboard-handlers/KeyHandler-AudioExplorer.js');const _DefaultProviderConfiguration={ProviderIdentifier:'RetoldRemote-GalleryNavigation',AutoInitialize:true,AutoSolveWithApp:false};class GalleryNavigationProvider extends libPictProvider{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this._columnsPerRow=4;this._keydownBound=false;this._helpPanelVisible=false;this._sidebarFocused=false;this._sidebarCursorIndex=0;}/**
|
|
9455
9560
|
* Calculate how many columns are in the current gallery grid by
|
|
9456
9561
|
* inspecting the rendered DOM. In list mode this is always 1.
|
|
9457
9562
|
*/recalculateColumns(){let tmpRemote=this.pict.AppData.RetoldRemote;// List mode is always a single column
|
|
@@ -9615,7 +9720,7 @@ fetch('/api/media/open',{method:'POST',headers:{'Content-Type':'application/json
|
|
|
9615
9720
|
// On macOS/Linux our custom handlers URL-decode, so we encode.
|
|
9616
9721
|
let tmpIsWindows=/Windows/.test(navigator.userAgent);let tmpVLCURL=tmpIsWindows?'vlc://'+tmpStreamURL:'vlc://'+encodeURIComponent(tmpStreamURL);this.pict.providers['RetoldRemote-ToastNotification'].showOverlayIndicator('Opening VLC...');// Use a temporary anchor element to trigger the protocol handler
|
|
9617
9722
|
// without navigating the current page away
|
|
9618
|
-
let tmpLink=document.createElement('a');tmpLink.href=tmpVLCURL;tmpLink.style.display='none';document.body.appendChild(tmpLink);tmpLink.click();document.body.removeChild(tmpLink);}}GalleryNavigationProvider.default_configuration=_DefaultProviderConfiguration;module.exports=GalleryNavigationProvider;},{"./keyboard-handlers/KeyHandler-AudioExplorer.js":
|
|
9723
|
+
let tmpLink=document.createElement('a');tmpLink.href=tmpVLCURL;tmpLink.style.display='none';document.body.appendChild(tmpLink);tmpLink.click();document.body.removeChild(tmpLink);}}GalleryNavigationProvider.default_configuration=_DefaultProviderConfiguration;module.exports=GalleryNavigationProvider;},{"./keyboard-handlers/KeyHandler-AudioExplorer.js":124,"./keyboard-handlers/KeyHandler-Gallery.js":125,"./keyboard-handlers/KeyHandler-Sidebar.js":126,"./keyboard-handlers/KeyHandler-VideoExplorer.js":127,"./keyboard-handlers/KeyHandler-Viewer.js":128,"pict-provider":46}],120:[function(require,module,exports){const libPictProvider=require('pict-provider');const _DefaultProviderConfiguration={ProviderIdentifier:'RetoldRemote-Provider',AutoInitialize:true,AutoSolveWithApp:false};class RetoldRemoteProvider extends libPictProvider{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);// Client-side cache: path -> hash and hash -> path
|
|
9619
9724
|
this._pathToHash={};this._hashToPath={};}/**
|
|
9620
9725
|
* Fetch the server's media processing capabilities.
|
|
9621
9726
|
*
|
|
@@ -9697,7 +9802,7 @@ if(pData&&pData.Hash&&pData.Path){this.registerHash(pData.Path,pData.Hash);}fCal
|
|
|
9697
9802
|
*
|
|
9698
9803
|
* @param {string} pExtension - Lowercase extension
|
|
9699
9804
|
* @returns {boolean}
|
|
9700
|
-
*/_isImageExtension(pExtension){let tmpImageExtensions={'png':true,'jpg':true,'jpeg':true,'gif':true,'webp':true,'svg':true,'bmp':true,'ico':true,'avif':true,'tiff':true,'tif':true};return!!tmpImageExtensions[pExtension];}}RetoldRemoteProvider.default_configuration=_DefaultProviderConfiguration;module.exports=RetoldRemoteProvider;},{"pict-provider":46}],
|
|
9805
|
+
*/_isImageExtension(pExtension){let tmpImageExtensions={'png':true,'jpg':true,'jpeg':true,'gif':true,'webp':true,'svg':true,'bmp':true,'ico':true,'avif':true,'tiff':true,'tif':true};return!!tmpImageExtensions[pExtension];}}RetoldRemoteProvider.default_configuration=_DefaultProviderConfiguration;module.exports=RetoldRemoteProvider;},{"pict-provider":46}],121:[function(require,module,exports){const libPictProvider=require('pict-provider');const _DefaultProviderConfiguration={"ProviderIdentifier":"RetoldRemote-Icons","AutoInitialize":true,"AutoInitializeOrdinal":0,"AutoSolveWithApp":true,"AutoSolveOrdinal":0};// ====================================================================
|
|
9701
9806
|
// DEFAULT DARK-THEME COLOR PALETTE
|
|
9702
9807
|
//
|
|
9703
9808
|
// Designed for retold-remote's dark navy background (#16162B).
|
|
@@ -9838,7 +9943,7 @@ return this.getIcon('file',tmpSize);}/**
|
|
|
9838
9943
|
* @returns {Object} Extension-to-icon name map
|
|
9839
9944
|
*/getExtensionMap(){return Object.assign({},this._extensionMap);}/**
|
|
9840
9945
|
* Inject CSS classes for icon sizing into the pict CSSMap.
|
|
9841
|
-
*/injectCSS(){if(this._cssInjected){return;}if(this.pict&&this.pict.CSSMap){this.pict.CSSMap.addCSS('RetoldRemoteIcons','.retold-remote-icon { display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; }\n'+'.retold-remote-icon svg { display: block; }\n'+'.retold-remote-icon-sm svg { width: 16px; height: 16px; }\n'+'.retold-remote-icon-md svg { width: 48px; height: 48px; }\n'+'.retold-remote-icon-lg svg { width: 64px; height: 64px; }\n'+'.retold-remote-icon-xl svg { width: 96px; height: 96px; }\n');this._cssInjected=true;}}onAfterInitialize(){this.injectCSS();return super.onAfterInitialize();}}module.exports=RetoldRemoteIconProvider;module.exports.default_configuration=_DefaultProviderConfiguration;module.exports.DefaultColors=_DefaultColors;},{"pict-provider":46,"pict-section-filebrowser/source/providers/Pict-Provider-FileBrowserIcons.js":56}],
|
|
9946
|
+
*/injectCSS(){if(this._cssInjected){return;}if(this.pict&&this.pict.CSSMap){this.pict.CSSMap.addCSS('RetoldRemoteIcons','.retold-remote-icon { display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; }\n'+'.retold-remote-icon svg { display: block; }\n'+'.retold-remote-icon-sm svg { width: 16px; height: 16px; }\n'+'.retold-remote-icon-md svg { width: 48px; height: 48px; }\n'+'.retold-remote-icon-lg svg { width: 64px; height: 64px; }\n'+'.retold-remote-icon-xl svg { width: 96px; height: 96px; }\n');this._cssInjected=true;}}onAfterInitialize(){this.injectCSS();return super.onAfterInitialize();}}module.exports=RetoldRemoteIconProvider;module.exports.default_configuration=_DefaultProviderConfiguration;module.exports.DefaultColors=_DefaultColors;},{"pict-provider":46,"pict-section-filebrowser/source/providers/Pict-Provider-FileBrowserIcons.js":56}],122:[function(require,module,exports){const libPictProvider=require('pict-provider');const _ProviderConfiguration={ProviderIdentifier:'RetoldRemote-Theme',AutoInitialize:true,AutoInitializeOrdinal:0};/**
|
|
9842
9947
|
* Theme provider for retold-remote.
|
|
9843
9948
|
*
|
|
9844
9949
|
* Manages 15 themes (5 grey-only + 10 fun) via CSS custom properties.
|
|
@@ -9877,7 +9982,7 @@ let tmpRemote=this.pict.AppData.RetoldRemote;if(tmpRemote){tmpRemote.Theme=pThem
|
|
|
9877
9982
|
*
|
|
9878
9983
|
* @param {string} pThemeKey
|
|
9879
9984
|
* @returns {Object|null}
|
|
9880
|
-
*/getTheme(pThemeKey){return this._themes[pThemeKey]||null;}}RetoldRemoteThemeProvider.default_configuration=_ProviderConfiguration;module.exports=RetoldRemoteThemeProvider;},{"pict-provider":46}],
|
|
9985
|
+
*/getTheme(pThemeKey){return this._themes[pThemeKey]||null;}}RetoldRemoteThemeProvider.default_configuration=_ProviderConfiguration;module.exports=RetoldRemoteThemeProvider;},{"pict-provider":46}],123:[function(require,module,exports){const libPictProvider=require('pict-provider');const _DefaultProviderConfiguration={ProviderIdentifier:'RetoldRemote-ToastNotification',AutoInitialize:true,AutoSolveWithApp:false};class ToastNotificationProvider extends libPictProvider{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='RetoldRemoteProvider';this._overlayTimeout=null;}/**
|
|
9881
9986
|
* Show a brief overlay indicator inside the viewer body.
|
|
9882
9987
|
*
|
|
9883
9988
|
* Reuses the #RetoldRemote-FitIndicator element, creating it if needed.
|
|
@@ -9892,12 +9997,12 @@ let tmpRemote=this.pict.AppData.RetoldRemote;if(tmpRemote){tmpRemote.Theme=pThem
|
|
|
9892
9997
|
*
|
|
9893
9998
|
* @param {string} pMessage - Text to display
|
|
9894
9999
|
* @param {number} pDuration - Milliseconds before removal (default 2000)
|
|
9895
|
-
*/showToast(pMessage,pDuration){let tmpDuration=pDuration||2000;let tmpExisting=document.querySelector('.retold-remote-toast');if(tmpExisting){tmpExisting.remove();}let tmpToast=document.createElement('div');tmpToast.className='retold-remote-toast';tmpToast.textContent=pMessage;document.body.appendChild(tmpToast);setTimeout(function(){if(tmpToast.parentNode){tmpToast.remove();}},tmpDuration);}}ToastNotificationProvider.default_configuration=_DefaultProviderConfiguration;module.exports=ToastNotificationProvider;},{"pict-provider":46}],
|
|
10000
|
+
*/showToast(pMessage,pDuration){let tmpDuration=pDuration||2000;let tmpExisting=document.querySelector('.retold-remote-toast');if(tmpExisting){tmpExisting.remove();}let tmpToast=document.createElement('div');tmpToast.className='retold-remote-toast';tmpToast.textContent=pMessage;document.body.appendChild(tmpToast);setTimeout(function(){if(tmpToast.parentNode){tmpToast.remove();}},tmpDuration);}}ToastNotificationProvider.default_configuration=_DefaultProviderConfiguration;module.exports=ToastNotificationProvider;},{"pict-provider":46}],124:[function(require,module,exports){/**
|
|
9896
10001
|
* Audio explorer mode keyboard handler.
|
|
9897
10002
|
*
|
|
9898
10003
|
* @param {GalleryNavigationProvider} pGalleryNav - The provider instance
|
|
9899
10004
|
* @param {KeyboardEvent} pEvent - The keyboard event
|
|
9900
|
-
*/function handleAudioExplorerKey(pGalleryNav,pEvent){let tmpAEX=pGalleryNav.pict.views['RetoldRemote-AudioExplorer'];if(!tmpAEX){return;}switch(pEvent.key){case'Escape':pEvent.preventDefault();if(tmpAEX._selectionStart>=0){tmpAEX.clearSelection();}else{tmpAEX.goBack();}break;case'+':case'=':pEvent.preventDefault();tmpAEX.zoomIn();break;case'-':case'_':pEvent.preventDefault();tmpAEX.zoomOut();break;case'0':pEvent.preventDefault();tmpAEX.zoomToFit();break;case'z':case'Z':pEvent.preventDefault();tmpAEX.zoomToSelection();break;case' ':pEvent.preventDefault();tmpAEX.playSelection();break;case'a':pEvent.preventDefault();{let tmpRemote=pGalleryNav.pict.AppData.RetoldRemote;let tmpCollMgr=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollMgr){if(tmpRemote.LastUsedCollectionGUID){tmpCollMgr.addAudioSnippetToCollection(tmpRemote.LastUsedCollectionGUID);}else{let tmpTopBar=pGalleryNav.pict.views['ContentEditor-TopBar'];if(tmpTopBar&&typeof tmpTopBar.showAddToCollectionDropdown==='function'){tmpTopBar.showAddToCollectionDropdown();}}}}break;case'b':pEvent.preventDefault();{let tmpCollManager=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollManager){tmpCollManager.togglePanel();}}break;}}module.exports=handleAudioExplorerKey;},{}],
|
|
10005
|
+
*/function handleAudioExplorerKey(pGalleryNav,pEvent){let tmpAEX=pGalleryNav.pict.views['RetoldRemote-AudioExplorer'];if(!tmpAEX){return;}switch(pEvent.key){case'Escape':pEvent.preventDefault();if(tmpAEX._selectionStart>=0){tmpAEX.clearSelection();}else{tmpAEX.goBack();}break;case'+':case'=':pEvent.preventDefault();tmpAEX.zoomIn();break;case'-':case'_':pEvent.preventDefault();tmpAEX.zoomOut();break;case'0':pEvent.preventDefault();tmpAEX.zoomToFit();break;case'z':case'Z':pEvent.preventDefault();tmpAEX.zoomToSelection();break;case' ':pEvent.preventDefault();tmpAEX.playSelection();break;case'a':pEvent.preventDefault();{let tmpRemote=pGalleryNav.pict.AppData.RetoldRemote;let tmpCollMgr=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollMgr){if(tmpRemote.LastUsedCollectionGUID){tmpCollMgr.addAudioSnippetToCollection(tmpRemote.LastUsedCollectionGUID);}else{let tmpTopBar=pGalleryNav.pict.views['ContentEditor-TopBar'];if(tmpTopBar&&typeof tmpTopBar.showAddToCollectionDropdown==='function'){tmpTopBar.showAddToCollectionDropdown();}}}}break;case'b':pEvent.preventDefault();{let tmpCollManager=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollManager){tmpCollManager.togglePanel();}}break;}}module.exports=handleAudioExplorerKey;},{}],125:[function(require,module,exports){/**
|
|
9901
10006
|
* Gallery mode keyboard handler.
|
|
9902
10007
|
*
|
|
9903
10008
|
* @param {GalleryNavigationProvider} pGalleryNav - The provider instance
|
|
@@ -9906,7 +10011,7 @@ let tmpRemote=this.pict.AppData.RetoldRemote;if(tmpRemote){tmpRemote.Theme=pThem
|
|
|
9906
10011
|
pGalleryNav._showFilterBar();let tmpGalleryView=pGalleryNav.pict.views['RetoldRemote-Gallery'];if(tmpGalleryView){tmpGalleryView.toggleFilterPanel();}}break;case's':pEvent.preventDefault();{// Ensure the filter bar is visible first
|
|
9907
10012
|
pGalleryNav._showFilterBar();setTimeout(()=>{let tmpSortSelect=document.getElementById('RetoldRemote-Gallery-Sort');if(tmpSortSelect){tmpSortSelect.focus();}},50);}break;case'c':pEvent.preventDefault();pGalleryNav._toggleSettingsPanel();break;case'a':pEvent.preventDefault();{let tmpCollMgr=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollMgr){let tmpCursorItem=tmpItems[tmpIndex];if(tmpCursorItem&&tmpRemote.LastUsedCollectionGUID){// Quick-add the highlighted gallery item to the last-used collection
|
|
9908
10013
|
let tmpAddItem={Type:tmpCursorItem.Type==='folder'||tmpCursorItem.Type==='archive'?'folder':'file',Path:tmpCursorItem.Path||'',Hash:tmpCursorItem.Hash||'',Label:''};tmpCollMgr.addItemsToCollection(tmpRemote.LastUsedCollectionGUID,[tmpAddItem]);}else{// No last-used collection or no item — open the topbar dropdown
|
|
9909
|
-
let tmpTopBar=pGalleryNav.pict.views['ContentEditor-TopBar'];if(tmpTopBar&&typeof tmpTopBar.showAddToCollectionDropdown==='function'){tmpTopBar.showAddToCollectionDropdown();}}}}break;case'b':pEvent.preventDefault();{let tmpCollManager=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollManager){tmpCollManager.togglePanel();}}break;case'd':pEvent.preventDefault();pGalleryNav._toggleDistractionFree();break;case'e':pEvent.preventDefault();{let tmpItem=tmpItems[tmpIndex];if(tmpItem&&tmpItem.Type!=='folder'&&tmpItem.Type!=='archive'){let tmpFilterSort=pGalleryNav.pict.providers['RetoldRemote-GalleryFilterSort'];let tmpCat=tmpFilterSort?tmpFilterSort.getCategory(tmpItem.Extension):'';if(tmpCat==='video'){let tmpVEX=pGalleryNav.pict.views['RetoldRemote-VideoExplorer'];if(tmpVEX){tmpVEX.showExplorer(tmpItem.Path);}}}}break;}}module.exports=handleGalleryKey;},{}],
|
|
10014
|
+
let tmpTopBar=pGalleryNav.pict.views['ContentEditor-TopBar'];if(tmpTopBar&&typeof tmpTopBar.showAddToCollectionDropdown==='function'){tmpTopBar.showAddToCollectionDropdown();}}}}break;case'b':pEvent.preventDefault();{let tmpCollManager=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollManager){tmpCollManager.togglePanel();}}break;case'd':pEvent.preventDefault();pGalleryNav._toggleDistractionFree();break;case'e':pEvent.preventDefault();{let tmpItem=tmpItems[tmpIndex];if(tmpItem&&tmpItem.Type!=='folder'&&tmpItem.Type!=='archive'){let tmpFilterSort=pGalleryNav.pict.providers['RetoldRemote-GalleryFilterSort'];let tmpCat=tmpFilterSort?tmpFilterSort.getCategory(tmpItem.Extension):'';if(tmpCat==='video'){let tmpVEX=pGalleryNav.pict.views['RetoldRemote-VideoExplorer'];if(tmpVEX){tmpVEX.showExplorer(tmpItem.Path);}}}}break;}}module.exports=handleGalleryKey;},{}],126:[function(require,module,exports){/**
|
|
9910
10015
|
* Sidebar file list keyboard handler.
|
|
9911
10016
|
*
|
|
9912
10017
|
* @param {GalleryNavigationProvider} pGalleryNav - The provider instance
|
|
@@ -9914,12 +10019,12 @@ let tmpTopBar=pGalleryNav.pict.views['ContentEditor-TopBar'];if(tmpTopBar&&typeo
|
|
|
9914
10019
|
*/function handleSidebarKey(pGalleryNav,pEvent){let tmpRows=document.querySelectorAll('#Pict-FileBrowser-DetailRows .pict-fb-detail-row');let tmpCount=tmpRows.length;if(tmpCount===0){// Nothing in the sidebar, bail back to gallery
|
|
9915
10020
|
pGalleryNav._blurSidebar();return;}switch(pEvent.key){case'ArrowDown':pEvent.preventDefault();pGalleryNav._moveSidebarCursor(Math.min(pGalleryNav._sidebarCursorIndex+1,tmpCount-1));break;case'ArrowUp':pEvent.preventDefault();pGalleryNav._moveSidebarCursor(Math.max(pGalleryNav._sidebarCursorIndex-1,0));break;case'Home':pEvent.preventDefault();pGalleryNav._moveSidebarCursor(0);break;case'End':pEvent.preventDefault();pGalleryNav._moveSidebarCursor(tmpCount-1);break;case'Enter':pEvent.preventDefault();{// Click the focused row to open it (folder or file)
|
|
9916
10021
|
let tmpRow=tmpRows[pGalleryNav._sidebarCursorIndex];if(tmpRow){// Fire the dblclick handler which opens folders / selects files
|
|
9917
|
-
let tmpDblClickHandler=tmpRow.getAttribute('ondblclick');if(tmpDblClickHandler){new Function(tmpDblClickHandler).call(tmpRow);}}}break;case'Escape':pEvent.preventDefault();pGalleryNav._blurSidebar();break;}}module.exports=handleSidebarKey;},{}],
|
|
10022
|
+
let tmpDblClickHandler=tmpRow.getAttribute('ondblclick');if(tmpDblClickHandler){new Function(tmpDblClickHandler).call(tmpRow);}}}break;case'Escape':pEvent.preventDefault();pGalleryNav._blurSidebar();break;}}module.exports=handleSidebarKey;},{}],127:[function(require,module,exports){/**
|
|
9918
10023
|
* Video explorer mode keyboard handler.
|
|
9919
10024
|
*
|
|
9920
10025
|
* @param {GalleryNavigationProvider} pGalleryNav - The provider instance
|
|
9921
10026
|
* @param {KeyboardEvent} pEvent - The keyboard event
|
|
9922
|
-
*/function handleVideoExplorerKey(pGalleryNav,pEvent){let tmpRemote=pGalleryNav.pict.AppData.RetoldRemote;switch(pEvent.key){case'Escape':pEvent.preventDefault();let tmpVEX=pGalleryNav.pict.views['RetoldRemote-VideoExplorer'];if(tmpVEX){tmpVEX.goBack();}break;case'a':pEvent.preventDefault();{let tmpCollMgr=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollMgr){if(tmpRemote.LastUsedCollectionGUID){tmpCollMgr.addVideoFrameToCollection(tmpRemote.LastUsedCollectionGUID);}else{let tmpTopBar=pGalleryNav.pict.views['ContentEditor-TopBar'];if(tmpTopBar&&typeof tmpTopBar.showAddToCollectionDropdown==='function'){tmpTopBar.showAddToCollectionDropdown();}}}}break;case'b':pEvent.preventDefault();{let tmpCollManager=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollManager){tmpCollManager.togglePanel();}}break;}}module.exports=handleVideoExplorerKey;},{}],
|
|
10027
|
+
*/function handleVideoExplorerKey(pGalleryNav,pEvent){let tmpRemote=pGalleryNav.pict.AppData.RetoldRemote;switch(pEvent.key){case'Escape':pEvent.preventDefault();let tmpVEX=pGalleryNav.pict.views['RetoldRemote-VideoExplorer'];if(tmpVEX){tmpVEX.goBack();}break;case'a':pEvent.preventDefault();{let tmpCollMgr=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollMgr){if(tmpRemote.LastUsedCollectionGUID){tmpCollMgr.addVideoFrameToCollection(tmpRemote.LastUsedCollectionGUID);}else{let tmpTopBar=pGalleryNav.pict.views['ContentEditor-TopBar'];if(tmpTopBar&&typeof tmpTopBar.showAddToCollectionDropdown==='function'){tmpTopBar.showAddToCollectionDropdown();}}}}break;case'b':pEvent.preventDefault();{let tmpCollManager=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollManager){tmpCollManager.togglePanel();}}break;}}module.exports=handleVideoExplorerKey;},{}],128:[function(require,module,exports){/**
|
|
9923
10028
|
* Viewer mode keyboard handler.
|
|
9924
10029
|
*
|
|
9925
10030
|
* @param {GalleryNavigationProvider} pGalleryNav - The provider instance
|
|
@@ -9927,7 +10032,7 @@ let tmpDblClickHandler=tmpRow.getAttribute('ondblclick');if(tmpDblClickHandler){
|
|
|
9927
10032
|
*/function handleViewerKey(pGalleryNav,pEvent){let tmpRemote=pGalleryNav.pict.AppData.RetoldRemote;// Video action menu mode — intercept keys for menu options
|
|
9928
10033
|
if(tmpRemote.VideoMenuActive&&tmpRemote.CurrentViewerMediaType==='video'){switch(pEvent.key){case'Escape':pEvent.preventDefault();pGalleryNav.closeViewer();return;case'ArrowRight':case'j':pEvent.preventDefault();pGalleryNav.nextFile();return;case'ArrowLeft':case'k':pEvent.preventDefault();pGalleryNav.prevFile();return;case'e':pEvent.preventDefault();let tmpVEX=pGalleryNav.pict.views['RetoldRemote-VideoExplorer'];if(tmpVEX){tmpVEX.showExplorer(tmpRemote.CurrentViewerFile);}return;case' ':case'Enter':pEvent.preventDefault();let tmpViewer=pGalleryNav.pict.views['RetoldRemote-MediaViewer'];if(tmpViewer){tmpViewer.playVideo();}return;case't':pEvent.preventDefault();let tmpMediaViewer=pGalleryNav.pict.views['RetoldRemote-MediaViewer'];if(tmpMediaViewer){tmpMediaViewer.loadVideoMenuFrame();}return;case'v':pEvent.preventDefault();pGalleryNav._streamWithVLC();return;}return;}switch(pEvent.key){case'Escape':pEvent.preventDefault();pGalleryNav.closeViewer();break;case'ArrowRight':case'j':pEvent.preventDefault();pGalleryNav.nextFile();break;case'ArrowLeft':case'k':pEvent.preventDefault();pGalleryNav.prevFile();break;case'f':pEvent.preventDefault();pGalleryNav._toggleFullscreen();break;case'i':pEvent.preventDefault();pGalleryNav._toggleFileInfo();break;case' ':pEvent.preventDefault();pGalleryNav._togglePlayPause();break;case'+':case'=':pEvent.preventDefault();pGalleryNav._zoomIn();break;case'-':pEvent.preventDefault();pGalleryNav._zoomOut();break;case'0':pEvent.preventDefault();pGalleryNav._zoomReset();break;case'z':pEvent.preventDefault();pGalleryNav._cycleFitMode();break;case'Enter':pEvent.preventDefault();pGalleryNav._streamWithVLC();break;case'v':pEvent.preventDefault();pGalleryNav._streamWithVLC();break;case'a':pEvent.preventDefault();{let tmpCollMgr=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollMgr){let tmpRemote=pGalleryNav.pict.AppData.RetoldRemote;if(tmpRemote.LastUsedCollectionGUID){// Quick-add the currently viewed file
|
|
9929
10034
|
tmpCollMgr.addCurrentFileToCollection(tmpRemote.LastUsedCollectionGUID);}else{// No last-used collection — open the picker
|
|
9930
|
-
let tmpTopBar=pGalleryNav.pict.views['ContentEditor-TopBar'];if(tmpTopBar&&typeof tmpTopBar.showAddToCollectionDropdown==='function'){tmpTopBar.showAddToCollectionDropdown();}}}}break;case'b':pEvent.preventDefault();{let tmpCollManager=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollManager){tmpCollManager.togglePanel();}}break;case'd':pEvent.preventDefault();pGalleryNav._toggleDistractionFree();break;case'1':pEvent.preventDefault();pGalleryNav.switchViewerType('image');break;case'2':pEvent.preventDefault();pGalleryNav.switchViewerType('video');break;case'3':pEvent.preventDefault();pGalleryNav.switchViewerType('audio');break;case'4':pEvent.preventDefault();pGalleryNav.switchViewerType('text');break;}}module.exports=handleViewerKey;},{}],
|
|
10035
|
+
let tmpTopBar=pGalleryNav.pict.views['ContentEditor-TopBar'];if(tmpTopBar&&typeof tmpTopBar.showAddToCollectionDropdown==='function'){tmpTopBar.showAddToCollectionDropdown();}}}}break;case'b':pEvent.preventDefault();{let tmpCollManager=pGalleryNav.pict.providers['RetoldRemote-CollectionManager'];if(tmpCollManager){tmpCollManager.togglePanel();}}break;case'd':pEvent.preventDefault();pGalleryNav._toggleDistractionFree();break;case'1':pEvent.preventDefault();pGalleryNav.switchViewerType('image');break;case'2':pEvent.preventDefault();pGalleryNav.switchViewerType('video');break;case'3':pEvent.preventDefault();pGalleryNav.switchViewerType('audio');break;case'4':pEvent.preventDefault();pGalleryNav.switchViewerType('text');break;}}module.exports=handleViewerKey;},{}],129:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"RetoldRemote-AudioExplorer",DefaultRenderable:"RetoldRemote-AudioExplorer",DefaultDestinationAddress:"#RetoldRemote-Viewer-Container",AutoRender:false,CSS:/*css*/`
|
|
9931
10036
|
.retold-remote-aex
|
|
9932
10037
|
{
|
|
9933
10038
|
display: flex;
|
|
@@ -10283,7 +10388,7 @@ if(this._resizeObserver){this._resizeObserver.disconnect();this._resizeObserver=
|
|
|
10283
10388
|
* Show an error message.
|
|
10284
10389
|
*
|
|
10285
10390
|
* @param {string} pMessage - Error message
|
|
10286
|
-
*/_showError(pMessage){let tmpBody=document.getElementById('RetoldRemote-AEX-Body');if(tmpBody){tmpBody.innerHTML='<div class="retold-remote-aex-error">'+'<div class="retold-remote-aex-error-message">'+this.pict.providers['RetoldRemote-FormattingUtilities'].escapeHTML(pMessage||'An error occurred.')+'</div>'+'<button class="retold-remote-aex-nav-btn" onclick="pict.views[\'RetoldRemote-AudioExplorer\'].goBack()">Back to Audio</button>'+'</div>';}}}RetoldRemoteAudioExplorerView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteAudioExplorerView;},{"pict-view":76}],
|
|
10391
|
+
*/_showError(pMessage){let tmpBody=document.getElementById('RetoldRemote-AEX-Body');if(tmpBody){tmpBody.innerHTML='<div class="retold-remote-aex-error">'+'<div class="retold-remote-aex-error-message">'+this.pict.providers['RetoldRemote-FormattingUtilities'].escapeHTML(pMessage||'An error occurred.')+'</div>'+'<button class="retold-remote-aex-nav-btn" onclick="pict.views[\'RetoldRemote-AudioExplorer\'].goBack()">Back to Audio</button>'+'</div>';}}}RetoldRemoteAudioExplorerView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteAudioExplorerView;},{"pict-view":76}],130:[function(require,module,exports){/**
|
|
10287
10392
|
* Retold Remote -- Collections Panel View
|
|
10288
10393
|
*
|
|
10289
10394
|
* Right-side flyout panel for managing user-defined collections.
|
|
@@ -10560,6 +10665,155 @@ if(this._resizeObserver){this._resizeObserver.disconnect();this._resizeObserver=
|
|
|
10560
10665
|
color: var(--retold-danger-muted, #e55);
|
|
10561
10666
|
background: rgba(200, 50, 50, 0.1);
|
|
10562
10667
|
}
|
|
10668
|
+
/* ---- Operation Plan mode ---- */
|
|
10669
|
+
.retold-remote-collections-op-controls
|
|
10670
|
+
{
|
|
10671
|
+
flex-direction: column;
|
|
10672
|
+
gap: 6px;
|
|
10673
|
+
}
|
|
10674
|
+
.retold-remote-collections-op-summary
|
|
10675
|
+
{
|
|
10676
|
+
font-size: 0.75rem;
|
|
10677
|
+
color: var(--retold-text-dim);
|
|
10678
|
+
padding: 4px 0;
|
|
10679
|
+
}
|
|
10680
|
+
.retold-remote-collections-op-buttons
|
|
10681
|
+
{
|
|
10682
|
+
display: flex;
|
|
10683
|
+
gap: 6px;
|
|
10684
|
+
}
|
|
10685
|
+
.retold-remote-collections-op-execute-btn
|
|
10686
|
+
{
|
|
10687
|
+
flex: 1;
|
|
10688
|
+
padding: 6px 12px;
|
|
10689
|
+
border: none;
|
|
10690
|
+
border-radius: 3px;
|
|
10691
|
+
background: var(--retold-accent, #4a90d9);
|
|
10692
|
+
color: #fff;
|
|
10693
|
+
font-size: 0.78rem;
|
|
10694
|
+
font-weight: 600;
|
|
10695
|
+
cursor: pointer;
|
|
10696
|
+
}
|
|
10697
|
+
.retold-remote-collections-op-execute-btn:hover
|
|
10698
|
+
{
|
|
10699
|
+
opacity: 0.9;
|
|
10700
|
+
}
|
|
10701
|
+
.retold-remote-collections-op-execute-btn:disabled
|
|
10702
|
+
{
|
|
10703
|
+
opacity: 0.5;
|
|
10704
|
+
cursor: default;
|
|
10705
|
+
}
|
|
10706
|
+
.retold-remote-collections-op-undo-btn
|
|
10707
|
+
{
|
|
10708
|
+
padding: 6px 12px;
|
|
10709
|
+
border: 1px solid var(--retold-border);
|
|
10710
|
+
border-radius: 3px;
|
|
10711
|
+
background: transparent;
|
|
10712
|
+
color: var(--retold-text-secondary);
|
|
10713
|
+
font-size: 0.78rem;
|
|
10714
|
+
cursor: pointer;
|
|
10715
|
+
}
|
|
10716
|
+
.retold-remote-collections-op-undo-btn:hover
|
|
10717
|
+
{
|
|
10718
|
+
background: var(--retold-bg-tertiary);
|
|
10719
|
+
}
|
|
10720
|
+
.retold-remote-collection-op-item
|
|
10721
|
+
{
|
|
10722
|
+
display: flex;
|
|
10723
|
+
align-items: center;
|
|
10724
|
+
gap: 4px;
|
|
10725
|
+
padding: 6px 8px;
|
|
10726
|
+
border-bottom: 1px solid var(--retold-border);
|
|
10727
|
+
font-size: 0.75rem;
|
|
10728
|
+
flex-wrap: wrap;
|
|
10729
|
+
}
|
|
10730
|
+
.retold-remote-collection-op-item.op-status-completed
|
|
10731
|
+
{
|
|
10732
|
+
opacity: 0.6;
|
|
10733
|
+
}
|
|
10734
|
+
.retold-remote-collection-op-item.op-status-skipped
|
|
10735
|
+
{
|
|
10736
|
+
opacity: 0.4;
|
|
10737
|
+
text-decoration: line-through;
|
|
10738
|
+
}
|
|
10739
|
+
.retold-remote-collection-op-item.op-status-failed
|
|
10740
|
+
{
|
|
10741
|
+
background: rgba(200, 50, 50, 0.05);
|
|
10742
|
+
}
|
|
10743
|
+
.retold-remote-collection-op-status
|
|
10744
|
+
{
|
|
10745
|
+
flex-shrink: 0;
|
|
10746
|
+
width: 16px;
|
|
10747
|
+
text-align: center;
|
|
10748
|
+
font-size: 0.8rem;
|
|
10749
|
+
}
|
|
10750
|
+
.op-status-completed .retold-remote-collection-op-status
|
|
10751
|
+
{
|
|
10752
|
+
color: var(--retold-success, #4a4);
|
|
10753
|
+
}
|
|
10754
|
+
.op-status-failed .retold-remote-collection-op-status
|
|
10755
|
+
{
|
|
10756
|
+
color: var(--retold-danger-muted, #e55);
|
|
10757
|
+
}
|
|
10758
|
+
.op-status-pending .retold-remote-collection-op-status
|
|
10759
|
+
{
|
|
10760
|
+
color: var(--retold-text-dim);
|
|
10761
|
+
}
|
|
10762
|
+
.retold-remote-collection-op-source
|
|
10763
|
+
{
|
|
10764
|
+
flex: 1;
|
|
10765
|
+
min-width: 0;
|
|
10766
|
+
overflow: hidden;
|
|
10767
|
+
text-overflow: ellipsis;
|
|
10768
|
+
white-space: nowrap;
|
|
10769
|
+
color: var(--retold-text-dim);
|
|
10770
|
+
}
|
|
10771
|
+
.retold-remote-collection-op-arrow
|
|
10772
|
+
{
|
|
10773
|
+
flex-shrink: 0;
|
|
10774
|
+
color: var(--retold-text-dim);
|
|
10775
|
+
padding: 0 2px;
|
|
10776
|
+
}
|
|
10777
|
+
.retold-remote-collection-op-dest
|
|
10778
|
+
{
|
|
10779
|
+
flex: 2;
|
|
10780
|
+
min-width: 0;
|
|
10781
|
+
overflow: hidden;
|
|
10782
|
+
text-overflow: ellipsis;
|
|
10783
|
+
white-space: nowrap;
|
|
10784
|
+
color: var(--retold-text-secondary);
|
|
10785
|
+
}
|
|
10786
|
+
.retold-remote-collection-op-dest-input
|
|
10787
|
+
{
|
|
10788
|
+
width: 100%;
|
|
10789
|
+
padding: 2px 4px;
|
|
10790
|
+
border: 1px solid var(--retold-accent);
|
|
10791
|
+
border-radius: 2px;
|
|
10792
|
+
background: var(--retold-bg-tertiary);
|
|
10793
|
+
color: var(--retold-text-secondary);
|
|
10794
|
+
font-size: 0.75rem;
|
|
10795
|
+
font-family: inherit;
|
|
10796
|
+
box-sizing: border-box;
|
|
10797
|
+
}
|
|
10798
|
+
.retold-remote-collection-op-badge
|
|
10799
|
+
{
|
|
10800
|
+
flex-shrink: 0;
|
|
10801
|
+
font-size: 0.6rem;
|
|
10802
|
+
padding: 1px 4px;
|
|
10803
|
+
border-radius: 2px;
|
|
10804
|
+
background: var(--retold-bg-tertiary);
|
|
10805
|
+
color: var(--retold-text-dim);
|
|
10806
|
+
text-transform: uppercase;
|
|
10807
|
+
font-weight: 600;
|
|
10808
|
+
letter-spacing: 0.3px;
|
|
10809
|
+
}
|
|
10810
|
+
.retold-remote-collection-op-error
|
|
10811
|
+
{
|
|
10812
|
+
width: 100%;
|
|
10813
|
+
font-size: 0.68rem;
|
|
10814
|
+
color: var(--retold-danger-muted, #e55);
|
|
10815
|
+
padding: 2px 0 0 20px;
|
|
10816
|
+
}
|
|
10563
10817
|
/* ---- Edit mode ---- */
|
|
10564
10818
|
.retold-remote-collections-edit
|
|
10565
10819
|
{
|
|
@@ -10677,9 +10931,12 @@ let tmpBody=document.createElement('div');tmpBody.className='retold-remote-colle
|
|
|
10677
10931
|
let tmpIconDiv=document.createElement('div');tmpIconDiv.className='retold-remote-collection-card-icon';if(tmpIconProvider&&typeof tmpIconProvider.getIcon==='function'){tmpIconDiv.innerHTML=tmpIconProvider.getIcon('bookmark',18);}else{tmpIconDiv.textContent='\u2630';}// Info
|
|
10678
10932
|
let tmpInfoDiv=document.createElement('div');tmpInfoDiv.className='retold-remote-collection-card-info';let tmpNameDiv=document.createElement('div');tmpNameDiv.className='retold-remote-collection-card-name';tmpNameDiv.textContent=tmpCollection.Name||'Untitled';let tmpMetaDiv=document.createElement('div');tmpMetaDiv.className='retold-remote-collection-card-meta';tmpMetaDiv.textContent=tmpCollection.ItemCount+' item'+(tmpCollection.ItemCount!==1?'s':'');tmpInfoDiv.appendChild(tmpNameDiv);tmpInfoDiv.appendChild(tmpMetaDiv);tmpCard.appendChild(tmpIconDiv);tmpCard.appendChild(tmpInfoDiv);pBody.appendChild(tmpCard);}}// -- Detail Mode ------------------------------------------------------
|
|
10679
10933
|
_renderDetailMode(pRoot){let tmpSelf=this;let tmpRemote=this.pict.AppData.RetoldRemote;let tmpManager=this.pict.providers['RetoldRemote-CollectionManager'];let tmpCollection=tmpRemote.ActiveCollection;pRoot.innerHTML='';if(!tmpCollection){pRoot.innerHTML='<div class="retold-remote-collections-empty">Loading...</div>';return;}// Header with back button and collection name
|
|
10680
|
-
let tmpHeader=document.createElement('div');tmpHeader.className='retold-remote-collections-header';let tmpBackBtn=document.createElement('button');tmpBackBtn.className='retold-remote-collections-header-btn';tmpBackBtn.title='Back to list';tmpBackBtn.textContent='\u2190';tmpBackBtn.onclick=()=>{tmpRemote.CollectionsPanelMode='list';tmpRemote.ActiveCollectionGUID=null;tmpRemote.ActiveCollection=null;tmpSelf.renderContent();};let tmpTitle=document.createElement('div');tmpTitle.className='retold-remote-collections-header-title';tmpTitle.textContent=tmpCollection.Name||'Untitled';let tmpEditBtn=document.createElement('button');tmpEditBtn.className='retold-remote-collections-header-btn';tmpEditBtn.title='Edit collection';tmpEditBtn.textContent='\u270E';tmpEditBtn.onclick=()=>{tmpRemote.CollectionsPanelMode='edit';tmpSelf.renderContent();};tmpHeader.appendChild(tmpBackBtn);tmpHeader.appendChild(tmpTitle);tmpHeader.appendChild(tmpEditBtn);pRoot.appendChild(tmpHeader);//
|
|
10681
|
-
let
|
|
10682
|
-
let
|
|
10934
|
+
let tmpHeader=document.createElement('div');tmpHeader.className='retold-remote-collections-header';let tmpBackBtn=document.createElement('button');tmpBackBtn.className='retold-remote-collections-header-btn';tmpBackBtn.title='Back to list';tmpBackBtn.textContent='\u2190';tmpBackBtn.onclick=()=>{tmpRemote.CollectionsPanelMode='list';tmpRemote.ActiveCollectionGUID=null;tmpRemote.ActiveCollection=null;tmpSelf.renderContent();};let tmpTitle=document.createElement('div');tmpTitle.className='retold-remote-collections-header-title';tmpTitle.textContent=tmpCollection.Name||'Untitled';let tmpEditBtn=document.createElement('button');tmpEditBtn.className='retold-remote-collections-header-btn';tmpEditBtn.title='Edit collection';tmpEditBtn.textContent='\u270E';tmpEditBtn.onclick=()=>{tmpRemote.CollectionsPanelMode='edit';tmpSelf.renderContent();};tmpHeader.appendChild(tmpBackBtn);tmpHeader.appendChild(tmpTitle);tmpHeader.appendChild(tmpEditBtn);pRoot.appendChild(tmpHeader);// Check if this is an operation-plan collection
|
|
10935
|
+
let tmpIsOperationPlan=tmpCollection.CollectionType==='operation-plan';if(tmpIsOperationPlan){// Operation plan controls: summary + execute/undo buttons
|
|
10936
|
+
let tmpOpControls=document.createElement('div');tmpOpControls.className='retold-remote-collections-detail-controls retold-remote-collections-op-controls';// Count pending, completed, failed, skipped
|
|
10937
|
+
let tmpItems=tmpCollection.Items||[];let tmpPending=0;let tmpCompleted=0;let tmpFailed=0;let tmpSkipped=0;for(let i=0;i<tmpItems.length;i++){let tmpStatus=tmpItems[i].OperationStatus;if(tmpStatus==='completed')tmpCompleted++;else if(tmpStatus==='failed')tmpFailed++;else if(tmpStatus==='skipped')tmpSkipped++;else if(tmpItems[i].Operation)tmpPending++;}let tmpSummary=document.createElement('div');tmpSummary.className='retold-remote-collections-op-summary';let tmpSummaryParts=[];if(tmpPending>0)tmpSummaryParts.push(tmpPending+' pending');if(tmpCompleted>0)tmpSummaryParts.push(tmpCompleted+' done');if(tmpFailed>0)tmpSummaryParts.push(tmpFailed+' failed');if(tmpSkipped>0)tmpSummaryParts.push(tmpSkipped+' skipped');tmpSummary.textContent=tmpSummaryParts.join(' \u00b7 ')||'No operations';tmpOpControls.appendChild(tmpSummary);let tmpBtnRow=document.createElement('div');tmpBtnRow.className='retold-remote-collections-op-buttons';if(tmpPending>0){let tmpExecBtn=document.createElement('button');tmpExecBtn.className='retold-remote-collections-op-execute-btn';tmpExecBtn.textContent='Execute '+tmpPending+' Move'+(tmpPending>1?'s':'');tmpExecBtn.onclick=()=>{tmpExecBtn.disabled=true;tmpExecBtn.textContent='Moving...';tmpManager.executeCollectionOperations(tmpCollection.GUID);};tmpBtnRow.appendChild(tmpExecBtn);}if(tmpCollection.OperationBatchGUID&&tmpCompleted>0){let tmpUndoBtn=document.createElement('button');tmpUndoBtn.className='retold-remote-collections-op-undo-btn';tmpUndoBtn.textContent='Undo';tmpUndoBtn.onclick=()=>{tmpUndoBtn.disabled=true;tmpUndoBtn.textContent='Undoing...';tmpManager.undoCollectionOperations(tmpCollection.GUID);};tmpBtnRow.appendChild(tmpUndoBtn);}tmpOpControls.appendChild(tmpBtnRow);pRoot.appendChild(tmpOpControls);}else{// Standard sort controls for bookmark collections
|
|
10938
|
+
let tmpControls=document.createElement('div');tmpControls.className='retold-remote-collections-detail-controls';let tmpSortSelect=document.createElement('select');tmpSortSelect.className='retold-remote-collections-sort-select';let tmpSortOptions=[{value:'manual',label:'Manual'},{value:'name',label:'Name'},{value:'modified',label:'Date Added'},{value:'type',label:'Type'}];for(let i=0;i<tmpSortOptions.length;i++){let tmpOpt=document.createElement('option');tmpOpt.value=tmpSortOptions[i].value;tmpOpt.textContent=tmpSortOptions[i].label;if(tmpCollection.SortMode===tmpSortOptions[i].value){tmpOpt.selected=true;}tmpSortSelect.appendChild(tmpOpt);}tmpSortSelect.onchange=pEvent=>{tmpManager.sortActiveCollection(pEvent.target.value,null);};let tmpDirBtn=document.createElement('button');tmpDirBtn.className='retold-remote-collections-sort-dir';tmpDirBtn.textContent=tmpCollection.SortDirection==='desc'?'\u2193':'\u2191';tmpDirBtn.title=tmpCollection.SortDirection==='desc'?'Descending':'Ascending';tmpDirBtn.onclick=()=>{let tmpNewDir=tmpRemote.ActiveCollection.SortDirection==='desc'?'asc':'desc';tmpManager.sortActiveCollection(null,tmpNewDir);};tmpControls.appendChild(tmpSortSelect);tmpControls.appendChild(tmpDirBtn);pRoot.appendChild(tmpControls);}// Item list
|
|
10939
|
+
let tmpBody=document.createElement('div');tmpBody.className='retold-remote-collections-body';pRoot.appendChild(tmpBody);if(tmpIsOperationPlan){this._renderOperationItemList(tmpBody,tmpCollection);}else{this._renderItemList(tmpBody,tmpCollection);}}_renderItemList(pBody,pCollection){let tmpSelf=this;let tmpRemote=this.pict.AppData.RetoldRemote;let tmpManager=this.pict.providers['RetoldRemote-CollectionManager'];let tmpItems=pCollection.Items||[];pBody.innerHTML='';if(tmpItems.length===0){let tmpEmpty=document.createElement('div');tmpEmpty.className='retold-remote-collections-empty';tmpEmpty.textContent='No items yet. Browse files and add them to this collection.';pBody.appendChild(tmpEmpty);return;}for(let i=0;i<tmpItems.length;i++){let tmpItem=tmpItems[i];let tmpRow=document.createElement('div');tmpRow.className='retold-remote-collection-item';tmpRow.setAttribute('data-item-id',tmpItem.ID);// Drag handle (for manual sort)
|
|
10683
10940
|
if(pCollection.SortMode==='manual'){let tmpDrag=document.createElement('div');tmpDrag.className='retold-remote-collection-item-drag';tmpDrag.textContent='\u2630';tmpDrag.draggable=true;tmpDrag.ondragstart=pEvent=>{tmpSelf._draggedItemId=tmpItem.ID;tmpRow.classList.add('dragging');pEvent.dataTransfer.effectAllowed='move';};tmpDrag.ondragend=()=>{tmpRow.classList.remove('dragging');tmpSelf._draggedItemId=null;// Remove all drag-over classes
|
|
10684
10941
|
let tmpAllItems=pBody.querySelectorAll('.retold-remote-collection-item');for(let j=0;j<tmpAllItems.length;j++){tmpAllItems[j].classList.remove('drag-over');}};tmpRow.appendChild(tmpDrag);}// Drop target events
|
|
10685
10942
|
tmpRow.ondragover=pEvent=>{pEvent.preventDefault();pEvent.dataTransfer.dropEffect='move';tmpRow.classList.add('drag-over');};tmpRow.ondragleave=()=>{tmpRow.classList.remove('drag-over');};tmpRow.ondrop=pEvent=>{pEvent.preventDefault();tmpRow.classList.remove('drag-over');if(tmpSelf._draggedItemId&&tmpSelf._draggedItemId!==tmpItem.ID){// Build new order: move dragged item before this item
|
|
@@ -10689,7 +10946,19 @@ let tmpNameDiv=document.createElement('div');tmpNameDiv.className='retold-remote
|
|
|
10689
10946
|
let tmpTypeDiv=document.createElement('div');tmpTypeDiv.className='retold-remote-collection-item-type';tmpTypeDiv.textContent=tmpItem.Type||'file';// Remove button
|
|
10690
10947
|
let tmpRemoveBtn=document.createElement('button');tmpRemoveBtn.className='retold-remote-collection-item-remove';tmpRemoveBtn.title='Remove from collection';tmpRemoveBtn.textContent='\u00d7';tmpRemoveBtn.onclick=pEvent=>{pEvent.stopPropagation();tmpManager.removeItemFromCollection(pCollection.GUID,tmpItem.ID);};// Click to navigate — set up collection browsing context
|
|
10691
10948
|
let tmpItemIndex=i;tmpRow.onclick=()=>{if(tmpItem.Type==='file'||tmpItem.Type==='subfile'||tmpItem.Type==='image-crop'||tmpItem.Type==='video-clip'||tmpItem.Type==='video-frame'){// Enter collection browsing mode so next/prev navigate through collection items
|
|
10692
|
-
tmpRemote.BrowsingCollection=true;tmpRemote.BrowsingCollectionIndex=tmpItemIndex;tmpSelf.pict.PictApplication.navigateToFile(tmpItem.Path);}else if(tmpItem.Type==='folder'||tmpItem.Type==='folder-contents'){tmpSelf.pict.PictApplication.loadFileList(tmpItem.Path);}};tmpRow.appendChild(tmpIconDiv);tmpRow.appendChild(tmpNameDiv);tmpRow.appendChild(tmpTypeDiv);tmpRow.appendChild(tmpRemoveBtn);pBody.appendChild(tmpRow);}}// --
|
|
10949
|
+
tmpRemote.BrowsingCollection=true;tmpRemote.BrowsingCollectionIndex=tmpItemIndex;tmpSelf.pict.PictApplication.navigateToFile(tmpItem.Path);}else if(tmpItem.Type==='folder'||tmpItem.Type==='folder-contents'){tmpSelf.pict.PictApplication.loadFileList(tmpItem.Path);}};tmpRow.appendChild(tmpIconDiv);tmpRow.appendChild(tmpNameDiv);tmpRow.appendChild(tmpTypeDiv);tmpRow.appendChild(tmpRemoveBtn);pBody.appendChild(tmpRow);}}// -- Operation Plan Item Rendering ------------------------------------
|
|
10950
|
+
_renderOperationItemList(pBody,pCollection){let tmpSelf=this;let tmpManager=this.pict.providers['RetoldRemote-CollectionManager'];let tmpItems=pCollection.Items||[];pBody.innerHTML='';if(tmpItems.length===0){let tmpEmpty=document.createElement('div');tmpEmpty.className='retold-remote-collections-empty';tmpEmpty.textContent='No items in this sort plan.';pBody.appendChild(tmpEmpty);return;}for(let i=0;i<tmpItems.length;i++){let tmpItem=tmpItems[i];let tmpRow=document.createElement('div');tmpRow.className='retold-remote-collection-op-item';// Status color
|
|
10951
|
+
let tmpStatus=tmpItem.OperationStatus||'pending';tmpRow.classList.add('op-status-'+tmpStatus);// Status indicator
|
|
10952
|
+
let tmpStatusDiv=document.createElement('div');tmpStatusDiv.className='retold-remote-collection-op-status';if(tmpStatus==='completed'){tmpStatusDiv.textContent='\u2713';tmpStatusDiv.title='Completed';}else if(tmpStatus==='failed'){tmpStatusDiv.textContent='\u2717';tmpStatusDiv.title=tmpItem.OperationError||'Failed';}else if(tmpStatus==='skipped'){tmpStatusDiv.textContent='\u2014';tmpStatusDiv.title='Skipped';}else{tmpStatusDiv.textContent='\u25CB';tmpStatusDiv.title='Pending';}// Source path (filename only, full path in tooltip)
|
|
10953
|
+
let tmpSourceDiv=document.createElement('div');tmpSourceDiv.className='retold-remote-collection-op-source';let tmpSourcePath=tmpItem.Path||'';tmpSourceDiv.textContent=tmpSourcePath.split('/').pop()||tmpSourcePath;tmpSourceDiv.title=tmpSourcePath;// Arrow
|
|
10954
|
+
let tmpArrow=document.createElement('div');tmpArrow.className='retold-remote-collection-op-arrow';tmpArrow.textContent='\u2192';// Destination path (editable)
|
|
10955
|
+
let tmpDestDiv=document.createElement('div');tmpDestDiv.className='retold-remote-collection-op-dest';let tmpDestPath=tmpItem.DestinationPath||'';tmpDestDiv.textContent=tmpDestPath||'(no destination)';tmpDestDiv.title=tmpDestPath;// Make destination editable on click (only for pending items)
|
|
10956
|
+
if(tmpStatus==='pending'){tmpDestDiv.style.cursor='pointer';tmpDestDiv.onclick=pEvent=>{pEvent.stopPropagation();tmpSelf._startEditDestination(tmpDestDiv,tmpItem,pCollection);};}// Operation badge
|
|
10957
|
+
let tmpOpBadge=document.createElement('div');tmpOpBadge.className='retold-remote-collection-op-badge';tmpOpBadge.textContent=(tmpItem.Operation||'move').toUpperCase();// Skip/remove button (only for pending items)
|
|
10958
|
+
let tmpSkipBtn=document.createElement('button');tmpSkipBtn.className='retold-remote-collection-item-remove';tmpSkipBtn.title='Skip this operation';tmpSkipBtn.textContent='\u00d7';if(tmpStatus==='pending'){tmpSkipBtn.onclick=pEvent=>{pEvent.stopPropagation();tmpManager.skipItemOperation(tmpItem.ID);};}else{tmpSkipBtn.style.visibility='hidden';}// Error message (if failed)
|
|
10959
|
+
if(tmpStatus==='failed'&&tmpItem.OperationError){let tmpErrorDiv=document.createElement('div');tmpErrorDiv.className='retold-remote-collection-op-error';tmpErrorDiv.textContent=tmpItem.OperationError;tmpRow.appendChild(tmpErrorDiv);}tmpRow.appendChild(tmpStatusDiv);tmpRow.appendChild(tmpSourceDiv);tmpRow.appendChild(tmpArrow);tmpRow.appendChild(tmpDestDiv);tmpRow.appendChild(tmpOpBadge);tmpRow.appendChild(tmpSkipBtn);pBody.appendChild(tmpRow);}}/**
|
|
10960
|
+
* Start inline editing of an operation item's destination path.
|
|
10961
|
+
*/_startEditDestination(pDestDiv,pItem,pCollection){let tmpSelf=this;let tmpManager=this.pict.providers['RetoldRemote-CollectionManager'];let tmpInput=document.createElement('input');tmpInput.type='text';tmpInput.className='retold-remote-collection-op-dest-input';tmpInput.value=pItem.DestinationPath||'';let tmpFinishEdit=()=>{let tmpNewDest=tmpInput.value.trim();if(tmpNewDest&&tmpNewDest!==pItem.DestinationPath){tmpManager.setItemDestination(pItem.ID,tmpNewDest);}pDestDiv.textContent=tmpNewDest||pItem.DestinationPath||'(no destination)';pDestDiv.title=tmpNewDest||pItem.DestinationPath||'';};tmpInput.onblur=tmpFinishEdit;tmpInput.onkeydown=pEvent=>{if(pEvent.key==='Enter'){pEvent.preventDefault();tmpInput.blur();}else if(pEvent.key==='Escape'){pEvent.preventDefault();pDestDiv.textContent=pItem.DestinationPath||'(no destination)';pDestDiv.title=pItem.DestinationPath||'';}};pDestDiv.textContent='';pDestDiv.appendChild(tmpInput);tmpInput.focus();tmpInput.select();}// -- Edit Mode --------------------------------------------------------
|
|
10693
10962
|
_renderEditMode(pRoot){let tmpSelf=this;let tmpRemote=this.pict.AppData.RetoldRemote;let tmpManager=this.pict.providers['RetoldRemote-CollectionManager'];let tmpCollection=tmpRemote.ActiveCollection;pRoot.innerHTML='';if(!tmpCollection){pRoot.innerHTML='<div class="retold-remote-collections-empty">No collection selected.</div>';return;}// Header
|
|
10694
10963
|
let tmpHeader=document.createElement('div');tmpHeader.className='retold-remote-collections-header';let tmpBackBtn=document.createElement('button');tmpBackBtn.className='retold-remote-collections-header-btn';tmpBackBtn.title='Back to detail';tmpBackBtn.textContent='\u2190';tmpBackBtn.onclick=()=>{tmpRemote.CollectionsPanelMode='detail';tmpSelf.renderContent();};let tmpTitle=document.createElement('div');tmpTitle.className='retold-remote-collections-header-title';tmpTitle.textContent='Edit Collection';tmpHeader.appendChild(tmpBackBtn);tmpHeader.appendChild(tmpTitle);pRoot.appendChild(tmpHeader);// Edit form
|
|
10695
10964
|
let tmpBody=document.createElement('div');tmpBody.className='retold-remote-collections-body';let tmpForm=document.createElement('div');tmpForm.className='retold-remote-collections-edit';// Name
|
|
@@ -10704,7 +10973,7 @@ let tmpDeleteBtn=document.createElement('button');tmpDeleteBtn.className='retold
|
|
|
10704
10973
|
*/_createEditGroup(pLabel,pType,pValue,pId){let tmpGroup=document.createElement('div');tmpGroup.className='retold-remote-collections-edit-group';let tmpLabel=document.createElement('div');tmpLabel.className='retold-remote-collections-edit-label';tmpLabel.textContent=pLabel;let tmpInput;if(pType==='textarea'){tmpInput=document.createElement('textarea');tmpInput.className='retold-remote-collections-edit-textarea';}else{tmpInput=document.createElement('input');tmpInput.className='retold-remote-collections-edit-input';tmpInput.type='text';}tmpInput.value=pValue;tmpInput.id='retold-remote-'+pId;tmpGroup.appendChild(tmpLabel);tmpGroup.appendChild(tmpInput);return tmpGroup;}// -- Helpers ----------------------------------------------------------
|
|
10705
10974
|
/**
|
|
10706
10975
|
* Get a text icon character for an item type.
|
|
10707
|
-
*/_getTypeIcon(pType,pMediaType){switch(pType){case'folder':case'folder-contents':return'\uD83D\uDCC1';case'subfile':return'\uD83D\uDDC4';case'image-crop':return'\u2702';case'video-clip':case'video-frame':return'\uD83C\uDFAC';default:break;}switch(pMediaType){case'image':return'\uD83D\uDDBC';case'video':return'\uD83C\uDFAC';case'audio':return'\uD83C\uDFB5';case'document':return'\uD83D\uDCC4';default:return'\uD83D\uDCC4';}}}RetoldRemoteCollectionsPanelView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteCollectionsPanelView;},{"pict-view":76}],
|
|
10976
|
+
*/_getTypeIcon(pType,pMediaType){switch(pType){case'folder':case'folder-contents':return'\uD83D\uDCC1';case'subfile':return'\uD83D\uDDC4';case'image-crop':return'\u2702';case'video-clip':case'video-frame':return'\uD83C\uDFAC';default:break;}switch(pMediaType){case'image':return'\uD83D\uDDBC';case'video':return'\uD83C\uDFAC';case'audio':return'\uD83C\uDFB5';case'document':return'\uD83D\uDCC4';default:return'\uD83D\uDCC4';}}}RetoldRemoteCollectionsPanelView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteCollectionsPanelView;},{"pict-view":76}],131:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"RetoldRemote-Gallery",DefaultRenderable:"RetoldRemote-Gallery-Grid",DefaultDestinationAddress:"#RetoldRemote-Gallery-Container",AutoRender:false,CSS:/*css*/`
|
|
10708
10977
|
.retold-remote-gallery-header
|
|
10709
10978
|
{
|
|
10710
10979
|
display: flex;
|
|
@@ -11529,7 +11798,7 @@ pEvent.preventDefault();}_hideLongPressTooltip(){if(this._longPressTooltipEl){if
|
|
|
11529
11798
|
* Get the media category for a file.
|
|
11530
11799
|
*/_getCategory(pExtension,pType){if(pType==='folder')return'folder';if(pType==='archive')return'archive';// Delegate to the filter/sort provider if available
|
|
11531
11800
|
let tmpFilterSort=this.pict.providers['RetoldRemote-GalleryFilterSort'];if(tmpFilterSort){return tmpFilterSort.getCategory(pExtension);}// Fallback
|
|
11532
|
-
let tmpExt=(pExtension||'').replace(/^\./,'').toLowerCase();if(tmpExt==='png'||tmpExt==='jpg'||tmpExt==='jpeg'||tmpExt==='gif'||tmpExt==='webp')return'image';if(tmpExt==='mp4'||tmpExt==='webm'||tmpExt==='mov')return'video';if(tmpExt==='mp3'||tmpExt==='wav'||tmpExt==='ogg')return'audio';if(tmpExt==='pdf')return'document';return'other';}}RetoldRemoteGalleryView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteGalleryView;},{"pict-view":76}],
|
|
11801
|
+
let tmpExt=(pExtension||'').replace(/^\./,'').toLowerCase();if(tmpExt==='png'||tmpExt==='jpg'||tmpExt==='jpeg'||tmpExt==='gif'||tmpExt==='webp')return'image';if(tmpExt==='mp4'||tmpExt==='webm'||tmpExt==='mov')return'video';if(tmpExt==='mp3'||tmpExt==='wav'||tmpExt==='ogg')return'audio';if(tmpExt==='pdf')return'document';return'other';}}RetoldRemoteGalleryView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteGalleryView;},{"pict-view":76}],132:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"RetoldRemote-ImageViewer",DefaultRenderable:"RetoldRemote-ImageViewer",DefaultDestinationAddress:"#RetoldRemote-Viewer-Container",AutoRender:false,CSS:/*css*/`
|
|
11533
11802
|
#RetoldRemote-ImageViewer-Img
|
|
11534
11803
|
{
|
|
11535
11804
|
image-orientation: from-image;
|
|
@@ -11595,12 +11864,13 @@ return{width:tmpNW,height:tmpNH};}}}/**
|
|
|
11595
11864
|
* @param {string} pMode - The mode identifier
|
|
11596
11865
|
*/_showFitModeIndicator(pMode){let tmpLabels={'fit':'Fit to Window','auto':'Original if Smaller','original':'Original Size'};let tmpLabel=tmpLabels[pMode]||pMode;this.pict.providers['RetoldRemote-ToastNotification'].showOverlayIndicator(tmpLabel,1200);}/**
|
|
11597
11866
|
* Clean up resize handler when navigating away.
|
|
11598
|
-
*/cleanup(){if(this._resizeHandler){window.removeEventListener('resize',this._resizeHandler);this._resizeHandler=null;}}}RetoldRemoteImageViewerView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteImageViewerView;},{"pict-view":76}],
|
|
11867
|
+
*/cleanup(){if(this._resizeHandler){window.removeEventListener('resize',this._resizeHandler);this._resizeHandler=null;}}}RetoldRemoteImageViewerView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteImageViewerView;},{"pict-view":76}],133:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"ContentEditor-Layout",DefaultRenderable:"RetoldRemote-Layout-Shell",DefaultDestinationAddress:"#ContentEditor-Application-Container",AutoRender:false,CSS:/*css*/`
|
|
11599
11868
|
#ContentEditor-Application-Container
|
|
11600
11869
|
{
|
|
11601
11870
|
display: flex;
|
|
11602
11871
|
flex-direction: column;
|
|
11603
11872
|
height: 100vh;
|
|
11873
|
+
height: 100dvh;
|
|
11604
11874
|
background: var(--retold-bg-primary);
|
|
11605
11875
|
color: var(--retold-text-primary);
|
|
11606
11876
|
font-family: var(--retold-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
|
|
@@ -11864,6 +12134,7 @@ return{width:tmpNW,height:tmpNH};}}}/**
|
|
|
11864
12134
|
{
|
|
11865
12135
|
width: 100% !important;
|
|
11866
12136
|
height: 33vh;
|
|
12137
|
+
height: 33dvh;
|
|
11867
12138
|
transition: height 0.2s ease;
|
|
11868
12139
|
flex-direction: column;
|
|
11869
12140
|
}
|
|
@@ -12027,7 +12298,7 @@ tmpHandle.addEventListener('dblclick',function(pEvent){pEvent.preventDefault();t
|
|
|
12027
12298
|
*/_setupCollectionsResizeHandle(){let tmpHandle=document.querySelector('.retold-remote-collections-resize-handle');let tmpWrap=document.getElementById('RetoldRemote-Collections-Wrap');if(!tmpHandle||!tmpWrap){return;}let tmpSelf=this;let tmpStartX=0;let tmpStartWidth=0;function onDragStart(pEvent){if(tmpWrap.classList.contains('collapsed')){return;}pEvent.preventDefault();tmpSelf._collectionsDragging=true;tmpHandle.classList.add('dragging');let tmpClientX=pEvent.touches?pEvent.touches[0].clientX:pEvent.clientX;tmpStartX=tmpClientX;tmpStartWidth=tmpWrap.getBoundingClientRect().width;document.addEventListener('mousemove',onDragMove);document.addEventListener('mouseup',onDragEnd);document.addEventListener('touchmove',onDragMove,{passive:false});document.addEventListener('touchend',onDragEnd);}function onDragMove(pEvent){if(!tmpSelf._collectionsDragging){return;}pEvent.preventDefault();let tmpClientX=pEvent.touches?pEvent.touches[0].clientX:pEvent.clientX;// Dragging left (negative deltaX) increases width
|
|
12028
12299
|
let tmpDelta=tmpStartX-tmpClientX;let tmpNewWidth=Math.max(150,Math.min(600,tmpStartWidth+tmpDelta));tmpWrap.style.width=tmpNewWidth+'px';}function onDragEnd(){if(!tmpSelf._collectionsDragging){return;}tmpSelf._collectionsDragging=false;tmpHandle.classList.remove('dragging');let tmpRemote=tmpSelf.pict.AppData.RetoldRemote;tmpRemote.CollectionsPanelWidth=tmpWrap.getBoundingClientRect().width;tmpSelf.pict.PictApplication.saveSettings();document.removeEventListener('mousemove',onDragMove);document.removeEventListener('mouseup',onDragEnd);document.removeEventListener('touchmove',onDragMove);document.removeEventListener('touchend',onDragEnd);// Recalculate gallery columns
|
|
12029
12300
|
let tmpGalleryNav=tmpSelf.pict.providers['RetoldRemote-GalleryNavigation'];if(tmpGalleryNav&&typeof tmpGalleryNav.recalculateColumns==='function'){tmpGalleryNav.recalculateColumns();}}tmpHandle.addEventListener('mousedown',onDragStart);tmpHandle.addEventListener('touchstart',onDragStart,{passive:false});// Double-click collapses the collections panel
|
|
12030
|
-
tmpHandle.addEventListener('dblclick',function(pEvent){pEvent.preventDefault();tmpSelf.toggleCollectionsPanel();});}}RetoldRemoteLayoutView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteLayoutView;},{"pict-view":76}],
|
|
12301
|
+
tmpHandle.addEventListener('dblclick',function(pEvent){pEvent.preventDefault();tmpSelf.toggleCollectionsPanel();});}}RetoldRemoteLayoutView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteLayoutView;},{"pict-view":76}],134:[function(require,module,exports){const libPictView=require('pict-view');const libPictSectionCode=require('pict-section-code');const _ViewConfiguration={ViewIdentifier:"RetoldRemote-MediaViewer",DefaultRenderable:"RetoldRemote-MediaViewer",DefaultDestinationAddress:"#RetoldRemote-Viewer-Container",AutoRender:false,CSS:/*css*/`
|
|
12031
12302
|
.retold-remote-viewer
|
|
12032
12303
|
{
|
|
12033
12304
|
display: flex;
|
|
@@ -12646,7 +12917,7 @@ tmpBook.loaded.navigation.then(pNav=>{tmpSelf._renderEbookTOC(pNav.toc);});}).ca
|
|
|
12646
12917
|
*/_loadFileInfo(pFilePath){let tmpSelf=this;let tmpProvider=this.pict.providers['RetoldRemote-Provider'];if(!tmpProvider){return;}tmpProvider.fetchMediaProbe(pFilePath,(pError,pData)=>{if(!pData){return;}// Populate the info overlay
|
|
12647
12918
|
let tmpOverlay=document.getElementById('RetoldRemote-FileInfo-Overlay');if(tmpOverlay){let tmpHTML='';if(pData.Size!==undefined){tmpHTML+='<div class="retold-remote-fileinfo-row"><span class="retold-remote-fileinfo-label">Size</span><span class="retold-remote-fileinfo-value">'+tmpSelf.pict.providers['RetoldRemote-FormattingUtilities'].formatFileSize(pData.Size)+'</span></div>';}if(pData.Width&&pData.Height){tmpHTML+='<div class="retold-remote-fileinfo-row"><span class="retold-remote-fileinfo-label">Dimensions</span><span class="retold-remote-fileinfo-value">'+pData.Width+' x '+pData.Height+'</span></div>';}if(pData.Duration){let tmpMin=Math.floor(pData.Duration/60);let tmpSec=Math.floor(pData.Duration%60);tmpHTML+='<div class="retold-remote-fileinfo-row"><span class="retold-remote-fileinfo-label">Duration</span><span class="retold-remote-fileinfo-value">'+tmpMin+':'+(tmpSec<10?'0':'')+tmpSec+'</span></div>';}if(pData.Codec){tmpHTML+='<div class="retold-remote-fileinfo-row"><span class="retold-remote-fileinfo-label">Codec</span><span class="retold-remote-fileinfo-value">'+pData.Codec+'</span></div>';}if(pData.Format){tmpHTML+='<div class="retold-remote-fileinfo-row"><span class="retold-remote-fileinfo-label">Format</span><span class="retold-remote-fileinfo-value">'+pData.Format+'</span></div>';}if(pData.Modified){tmpHTML+='<div class="retold-remote-fileinfo-row"><span class="retold-remote-fileinfo-label">Modified</span><span class="retold-remote-fileinfo-value">'+new Date(pData.Modified).toLocaleString()+'</span></div>';}if(pData.Path){tmpHTML+='<div class="retold-remote-fileinfo-row"><span class="retold-remote-fileinfo-label">Path</span><span class="retold-remote-fileinfo-value">'+pData.Path+'</span></div>';}tmpOverlay.innerHTML=tmpHTML;}// Populate the video stats bar (if viewing a video)
|
|
12648
12919
|
let tmpStatsBar=document.getElementById('RetoldRemote-VideoStats');if(tmpStatsBar){let tmpStatsHTML='';if(pData.Duration){let tmpMin=Math.floor(pData.Duration/60);let tmpSec=Math.floor(pData.Duration%60);tmpStatsHTML+='<span><span class="retold-remote-video-stat-label">Duration</span> <span class="retold-remote-video-stat-value">'+tmpMin+':'+(tmpSec<10?'0':'')+tmpSec+'</span></span>';}if(pData.Width&&pData.Height){tmpStatsHTML+='<span><span class="retold-remote-video-stat-label">Resolution</span> <span class="retold-remote-video-stat-value">'+pData.Width+'×'+pData.Height+'</span></span>';}if(pData.Codec){tmpStatsHTML+='<span><span class="retold-remote-video-stat-label">Codec</span> <span class="retold-remote-video-stat-value">'+pData.Codec+'</span></span>';}if(pData.Bitrate){let tmpBitrate=pData.Bitrate;let tmpBitrateStr;if(tmpBitrate>=1000000){tmpBitrateStr=(tmpBitrate/1000000).toFixed(1)+' Mbps';}else if(tmpBitrate>=1000){tmpBitrateStr=Math.round(tmpBitrate/1000)+' kbps';}else{tmpBitrateStr=tmpBitrate+' bps';}tmpStatsHTML+='<span><span class="retold-remote-video-stat-label">Bitrate</span> <span class="retold-remote-video-stat-value">'+tmpBitrateStr+'</span></span>';}if(pData.Size!==undefined){tmpStatsHTML+='<span><span class="retold-remote-video-stat-label">Size</span> <span class="retold-remote-video-stat-value">'+tmpSelf.pict.providers['RetoldRemote-FormattingUtilities'].formatFileSize(pData.Size)+'</span></span>';}// Preserve the Explore and VLC buttons if they exist
|
|
12649
|
-
let tmpExploreBtn=tmpStatsBar.querySelector('.retold-remote-explore-btn');let tmpExploreHTML=tmpExploreBtn?tmpExploreBtn.outerHTML:'';let tmpVLCBtn=tmpStatsBar.querySelector('.retold-remote-vlc-btn');let tmpVLCHTML=tmpVLCBtn?tmpVLCBtn.outerHTML:'';tmpStatsBar.innerHTML=tmpStatsHTML+tmpExploreHTML+tmpVLCHTML;}});}}RetoldRemoteMediaViewerView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteMediaViewerView;},{"pict-section-code":49,"pict-view":76}],
|
|
12920
|
+
let tmpExploreBtn=tmpStatsBar.querySelector('.retold-remote-explore-btn');let tmpExploreHTML=tmpExploreBtn?tmpExploreBtn.outerHTML:'';let tmpVLCBtn=tmpStatsBar.querySelector('.retold-remote-vlc-btn');let tmpVLCHTML=tmpVLCBtn?tmpVLCBtn.outerHTML:'';tmpStatsBar.innerHTML=tmpStatsHTML+tmpExploreHTML+tmpVLCHTML;}});}}RetoldRemoteMediaViewerView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteMediaViewerView;},{"pict-section-code":49,"pict-view":76}],135:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"RetoldRemote-SettingsPanel",DefaultRenderable:"RetoldRemote-SettingsPanel",DefaultDestinationAddress:"#RetoldRemote-Settings-Container",AutoRender:false,CSS:/*css*/`
|
|
12650
12921
|
.retold-remote-settings
|
|
12651
12922
|
{
|
|
12652
12923
|
padding: 12px;
|
|
@@ -12736,6 +13007,42 @@ let tmpExploreBtn=tmpStatsBar.querySelector('.retold-remote-explore-btn');let tm
|
|
|
12736
13007
|
background: var(--retold-bg-hover);
|
|
12737
13008
|
color: var(--retold-text-primary);
|
|
12738
13009
|
}
|
|
13010
|
+
.retold-remote-settings-input
|
|
13011
|
+
{
|
|
13012
|
+
width: 100%;
|
|
13013
|
+
padding: 5px 8px;
|
|
13014
|
+
border: 1px solid var(--retold-border);
|
|
13015
|
+
border-radius: 3px;
|
|
13016
|
+
background: var(--retold-bg-tertiary);
|
|
13017
|
+
color: var(--retold-text-secondary);
|
|
13018
|
+
font-size: 0.75rem;
|
|
13019
|
+
font-family: inherit;
|
|
13020
|
+
box-sizing: border-box;
|
|
13021
|
+
}
|
|
13022
|
+
.retold-remote-settings-input:focus
|
|
13023
|
+
{
|
|
13024
|
+
outline: none;
|
|
13025
|
+
border-color: var(--retold-accent);
|
|
13026
|
+
}
|
|
13027
|
+
.retold-remote-settings-input-row
|
|
13028
|
+
{
|
|
13029
|
+
margin-bottom: 8px;
|
|
13030
|
+
}
|
|
13031
|
+
.retold-remote-settings-input-label
|
|
13032
|
+
{
|
|
13033
|
+
display: block;
|
|
13034
|
+
font-size: 0.72rem;
|
|
13035
|
+
color: var(--retold-text-dim);
|
|
13036
|
+
margin-bottom: 3px;
|
|
13037
|
+
}
|
|
13038
|
+
.retold-remote-settings-template-preview
|
|
13039
|
+
{
|
|
13040
|
+
font-size: 0.68rem;
|
|
13041
|
+
color: var(--retold-text-dim);
|
|
13042
|
+
margin-top: 3px;
|
|
13043
|
+
font-style: italic;
|
|
13044
|
+
word-break: break-all;
|
|
13045
|
+
}
|
|
12739
13046
|
`};class RetoldRemoteSettingsPanelView extends libPictView{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);}onAfterRender(){super.onAfterRender();this._renderSettingsContent();}_renderSettingsContent(){let tmpContainer=document.getElementById('RetoldRemote-Settings-Container');if(!tmpContainer){return;}let tmpRemote=this.pict.AppData.RetoldRemote;let tmpCapabilities=tmpRemote.ServerCapabilities||{};let tmpHTML='<div class="retold-remote-settings">';// Appearance section (theme dropdown)
|
|
12740
13047
|
tmpHTML+='<div class="retold-remote-settings-section">';tmpHTML+='<div class="retold-remote-settings-section-title">Appearance</div>';tmpHTML+='<div class="retold-remote-settings-row">';tmpHTML+='<span class="retold-remote-settings-label">Theme</span>';tmpHTML+='<select class="retold-remote-settings-select" onchange="pict.views[\'RetoldRemote-SettingsPanel\'].changeTheme(this.value)">';let tmpThemeProvider=this.pict.providers['RetoldRemote-Theme'];if(tmpThemeProvider){let tmpThemes=tmpThemeProvider.getThemeList();let tmpCurrentTheme=tmpThemeProvider.getCurrentTheme();let tmpCurrentCategory='';for(let i=0;i<tmpThemes.length;i++){let tmpTheme=tmpThemes[i];if(tmpTheme.category!==tmpCurrentCategory){if(tmpCurrentCategory){tmpHTML+='</optgroup>';}tmpHTML+='<optgroup label="'+tmpTheme.category+'">';tmpCurrentCategory=tmpTheme.category;}tmpHTML+='<option value="'+tmpTheme.key+'"'+(tmpTheme.key===tmpCurrentTheme?' selected':'')+'>'+tmpTheme.name+'</option>';}if(tmpCurrentCategory){tmpHTML+='</optgroup>';}}tmpHTML+='</select>';tmpHTML+='</div>';tmpHTML+='</div>';// end appearance section
|
|
12741
13048
|
// Gallery section
|
|
@@ -12755,6 +13062,14 @@ tmpHTML+='<div class="retold-remote-settings-row">';tmpHTML+='<span class="retol
|
|
|
12755
13062
|
// Server capabilities
|
|
12756
13063
|
tmpHTML+='<div class="retold-remote-settings-section">';tmpHTML+='<div class="retold-remote-settings-section-title">Server Capabilities</div>';tmpHTML+='<div class="retold-remote-settings-capabilities">';let tmpTools=[{key:'sharp',label:'Sharp (image thumbnails)'},{key:'imagemagick',label:'ImageMagick (image fallback)'},{key:'ffmpeg',label:'ffmpeg (video thumbnails)'},{key:'ffprobe',label:'ffprobe (media metadata)'}];for(let i=0;i<tmpTools.length;i++){let tmpTool=tmpTools[i];let tmpAvailable=tmpCapabilities[tmpTool.key];tmpHTML+='<div class="retold-remote-settings-cap-row">';tmpHTML+='<span class="retold-remote-settings-cap-label">'+tmpTool.label+'</span>';tmpHTML+='<span class="'+(tmpAvailable?'retold-remote-settings-cap-yes':'retold-remote-settings-cap-no')+'">'+(tmpAvailable?'Available':'Not found')+'</span>';tmpHTML+='</div>';}// Hashed filenames status
|
|
12757
13064
|
tmpHTML+='<div class="retold-remote-settings-cap-row" style="margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--retold-border);">';tmpHTML+='<span class="retold-remote-settings-cap-label">Hashed filenames</span>';tmpHTML+='<span class="'+(tmpRemote.HashedFilenames?'retold-remote-settings-cap-yes':'retold-remote-settings-cap-no')+'">'+(tmpRemote.HashedFilenames?'Enabled':'Disabled')+'</span>';tmpHTML+='</div>';tmpHTML+='</div>';tmpHTML+='</div>';// end capabilities section
|
|
13065
|
+
// AI File Sort
|
|
13066
|
+
tmpHTML+='<div class="retold-remote-settings-section">';tmpHTML+='<div class="retold-remote-settings-section-title">AI File Sort</div>';let tmpAISortManager=this.pict.providers['RetoldRemote-AISortManager'];let tmpAISettings=tmpRemote.AISortSettings||{AIEndpoint:'http://localhost:11434',AIModel:'llama3.1',AIProvider:'ollama',NamingTemplate:'{artist}/{album}/{track} - {title}'};// AI Endpoint
|
|
13067
|
+
tmpHTML+='<div class="retold-remote-settings-input-row">';tmpHTML+='<label class="retold-remote-settings-input-label">AI Endpoint URL</label>';tmpHTML+='<input class="retold-remote-settings-input" type="text" id="RetoldRemote-AISortEndpoint" value="'+this._escapeAttr(tmpAISettings.AIEndpoint)+'" onchange="pict.views[\'RetoldRemote-SettingsPanel\'].changeAISetting(\'AIEndpoint\', this.value)" placeholder="http://localhost:11434">';tmpHTML+='</div>';// AI Model
|
|
13068
|
+
tmpHTML+='<div class="retold-remote-settings-input-row">';tmpHTML+='<label class="retold-remote-settings-input-label">Model</label>';tmpHTML+='<input class="retold-remote-settings-input" type="text" id="RetoldRemote-AISortModel" value="'+this._escapeAttr(tmpAISettings.AIModel)+'" onchange="pict.views[\'RetoldRemote-SettingsPanel\'].changeAISetting(\'AIModel\', this.value)" placeholder="llama3.1">';tmpHTML+='</div>';// AI Provider
|
|
13069
|
+
tmpHTML+='<div class="retold-remote-settings-row">';tmpHTML+='<span class="retold-remote-settings-label">Provider</span>';tmpHTML+='<select class="retold-remote-settings-select" onchange="pict.views[\'RetoldRemote-SettingsPanel\'].changeAISetting(\'AIProvider\', this.value)">';tmpHTML+='<option value="ollama"'+(tmpAISettings.AIProvider==='ollama'?' selected':'')+'>Ollama</option>';tmpHTML+='<option value="openai"'+(tmpAISettings.AIProvider==='openai'?' selected':'')+'>OpenAI-compatible</option>';tmpHTML+='</select>';tmpHTML+='</div>';// Naming Template
|
|
13070
|
+
tmpHTML+='<div class="retold-remote-settings-input-row" style="margin-top: 8px;">';tmpHTML+='<label class="retold-remote-settings-input-label">Naming Template</label>';tmpHTML+='<input class="retold-remote-settings-input" type="text" id="RetoldRemote-AISortTemplate" value="'+this._escapeAttr(tmpAISettings.NamingTemplate)+'" onchange="pict.views[\'RetoldRemote-SettingsPanel\'].changeAISetting(\'NamingTemplate\', this.value)" placeholder="{artist}/{album}/{track} - {title}">';// Template preview
|
|
13071
|
+
let tmpTemplatePreview=tmpAISortManager?tmpAISortManager.getTemplatePreview(tmpAISettings.NamingTemplate):'';if(tmpTemplatePreview){tmpHTML+='<div class="retold-remote-settings-template-preview">Preview: '+this._escapeHTML(tmpTemplatePreview)+'</div>';}tmpHTML+='</div>';// Test Connection button
|
|
13072
|
+
tmpHTML+='<button class="retold-remote-settings-vlc-btn" id="RetoldRemote-AISortTestBtn" onclick="pict.views[\'RetoldRemote-SettingsPanel\'].testAIConnection()" style="margin-top: 8px;">';tmpHTML+='Test Connection';tmpHTML+='</button>';tmpHTML+='</div>';// end AI sort section
|
|
12758
13073
|
// VLC Setup
|
|
12759
13074
|
tmpHTML+='<div class="retold-remote-settings-section">';tmpHTML+='<div class="retold-remote-settings-section-title">VLC Streaming</div>';tmpHTML+='<button class="retold-remote-settings-vlc-btn" onclick="pict.views[\'RetoldRemote-VLCSetup\'].openModal()">';tmpHTML+='VLC Protocol Setup';tmpHTML+='</button>';tmpHTML+='</div>';// Help button
|
|
12760
13075
|
tmpHTML+='<div class="retold-remote-settings-section">';tmpHTML+='<div class="retold-remote-settings-section-title">Help</div>';tmpHTML+='<button class="retold-remote-settings-vlc-btn" onclick="pict.providers[\'RetoldRemote-GalleryNavigation\']._toggleHelpPanel()">';tmpHTML+='Help (F1)';tmpHTML+='</button>';tmpHTML+='</div>';tmpHTML+='</div>';// end settings
|
|
@@ -12762,8 +13077,26 @@ tmpContainer.innerHTML=tmpHTML;}changeTheme(pThemeKey){let tmpThemeProvider=this
|
|
|
12762
13077
|
this._renderSettingsContent();}}changeSetting(pKey,pValue){let tmpRemote=this.pict.AppData.RetoldRemote;tmpRemote[pKey]=pValue;this.pict.PictApplication.saveSettings();// Re-render gallery if visible
|
|
12763
13078
|
if(tmpRemote.ActiveMode==='gallery'){let tmpGalleryView=this.pict.views['RetoldRemote-Gallery'];if(tmpGalleryView){tmpGalleryView.renderGallery();}}}toggleHiddenFiles(pChecked){let tmpRemote=this.pict.AppData.RetoldRemote;tmpRemote.ShowHiddenFiles=pChecked;this.pict.PictApplication.saveSettings();this.pict.PictApplication.syncHiddenFilesSetting(()=>{this.pict.PictApplication.loadFileList();});}toggleAutoplay(pKey,pChecked){let tmpRemote=this.pict.AppData.RetoldRemote;tmpRemote[pKey]=pChecked;this.pict.PictApplication.saveSettings();}toggleDistractionFreeNav(pChecked){let tmpRemote=this.pict.AppData.RetoldRemote;tmpRemote.DistractionFreeShowNav=pChecked;this.pict.PictApplication.saveSettings();// If currently in distraction-free mode, apply immediately
|
|
12764
13079
|
if(tmpRemote._distractionFreeMode){let tmpViewerHeader=document.querySelector('.retold-remote-viewer-header');if(tmpViewerHeader){tmpViewerHeader.style.display=pChecked?'':'none';}}}changeImageFitMode(pMode){let tmpImageViewer=this.pict.views['RetoldRemote-ImageViewer'];if(tmpImageViewer){tmpImageViewer.setFitMode(pMode);}else{let tmpRemote=this.pict.AppData.RetoldRemote;tmpRemote.ImageFitMode=pMode;this.pict.PictApplication.saveSettings();}}changeSortField(pValue){let tmpRemote=this.pict.AppData.RetoldRemote;tmpRemote.SortField=pValue;this.pict.PictApplication.saveSettings();this._refilterGallery();}changeSortDirection(pValue){let tmpRemote=this.pict.AppData.RetoldRemote;tmpRemote.SortDirection=pValue;this.pict.PictApplication.saveSettings();this._refilterGallery();}changeMediaFilter(pValue){let tmpRemote=this.pict.AppData.RetoldRemote;tmpRemote.GalleryFilter=pValue;if(tmpRemote.FilterState){tmpRemote.FilterState.MediaType=pValue;}this.pict.PictApplication.saveSettings();this._refilterGallery();}/**
|
|
13080
|
+
* Change an AI sort setting.
|
|
13081
|
+
*
|
|
13082
|
+
* @param {string} pKey - Setting key (AIEndpoint, AIModel, AIProvider, NamingTemplate)
|
|
13083
|
+
* @param {string} pValue - New value
|
|
13084
|
+
*/changeAISetting(pKey,pValue){let tmpAISortManager=this.pict.providers['RetoldRemote-AISortManager'];if(tmpAISortManager){let tmpUpdate={};tmpUpdate[pKey]=pValue;tmpAISortManager.updateSettings(tmpUpdate);}// Update the template preview if the template changed
|
|
13085
|
+
if(pKey==='NamingTemplate'){this._renderSettingsContent();}}/**
|
|
13086
|
+
* Test the AI endpoint connection.
|
|
13087
|
+
*/testAIConnection(){let tmpBtn=document.getElementById('RetoldRemote-AISortTestBtn');if(tmpBtn){tmpBtn.disabled=true;tmpBtn.textContent='Testing...';}let tmpAISortManager=this.pict.providers['RetoldRemote-AISortManager'];if(tmpAISortManager){tmpAISortManager.testConnection();}}/**
|
|
13088
|
+
* Escape HTML attribute values.
|
|
13089
|
+
*
|
|
13090
|
+
* @param {string} pStr
|
|
13091
|
+
* @returns {string}
|
|
13092
|
+
*/_escapeAttr(pStr){if(!pStr)return'';return String(pStr).replace(/&/g,'&').replace(/"/g,'"').replace(/</g,'<').replace(/>/g,'>');}/**
|
|
13093
|
+
* Escape HTML text content.
|
|
13094
|
+
*
|
|
13095
|
+
* @param {string} pStr
|
|
13096
|
+
* @returns {string}
|
|
13097
|
+
*/_escapeHTML(pStr){if(!pStr)return'';return String(pStr).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');}/**
|
|
12765
13098
|
* Re-run the filter/sort pipeline and refresh the gallery.
|
|
12766
|
-
*/_refilterGallery(){let tmpRemote=this.pict.AppData.RetoldRemote;let tmpFilterSort=this.pict.providers['RetoldRemote-GalleryFilterSort'];if(tmpFilterSort){tmpFilterSort.runFilterPipeline();}if(tmpRemote.ActiveMode==='gallery'){let tmpGalleryView=this.pict.views['RetoldRemote-Gallery'];if(tmpGalleryView){tmpGalleryView.renderGallery();}}}}RetoldRemoteSettingsPanelView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteSettingsPanelView;},{"pict-view":76}],
|
|
13099
|
+
*/_refilterGallery(){let tmpRemote=this.pict.AppData.RetoldRemote;let tmpFilterSort=this.pict.providers['RetoldRemote-GalleryFilterSort'];if(tmpFilterSort){tmpFilterSort.runFilterPipeline();}if(tmpRemote.ActiveMode==='gallery'){let tmpGalleryView=this.pict.views['RetoldRemote-Gallery'];if(tmpGalleryView){tmpGalleryView.renderGallery();}}}}RetoldRemoteSettingsPanelView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteSettingsPanelView;},{"pict-view":76}],136:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"ContentEditor-TopBar",DefaultRenderable:"RetoldRemote-TopBar",DefaultDestinationAddress:"#ContentEditor-TopBar-Container",AutoRender:false,CSS:/*css*/`
|
|
12767
13100
|
.retold-remote-topbar
|
|
12768
13101
|
{
|
|
12769
13102
|
display: flex;
|
|
@@ -13087,6 +13420,31 @@ if(tmpRemote._distractionFreeMode){let tmpViewerHeader=document.querySelector('.
|
|
|
13087
13420
|
border-color: var(--retold-text-muted);
|
|
13088
13421
|
background: rgba(128, 128, 128, 0.06);
|
|
13089
13422
|
}
|
|
13423
|
+
.retold-remote-topbar-aisort-btn
|
|
13424
|
+
{
|
|
13425
|
+
padding: 4px 8px;
|
|
13426
|
+
border: 1px solid var(--retold-border);
|
|
13427
|
+
border-radius: 3px;
|
|
13428
|
+
background: transparent;
|
|
13429
|
+
color: var(--retold-text-muted);
|
|
13430
|
+
font-size: 0.72rem;
|
|
13431
|
+
cursor: pointer;
|
|
13432
|
+
transition: color 0.15s, border-color 0.15s, background 0.15s;
|
|
13433
|
+
font-family: inherit;
|
|
13434
|
+
white-space: nowrap;
|
|
13435
|
+
}
|
|
13436
|
+
.retold-remote-topbar-aisort-btn:hover
|
|
13437
|
+
{
|
|
13438
|
+
color: var(--retold-text-primary);
|
|
13439
|
+
border-color: var(--retold-accent);
|
|
13440
|
+
background: rgba(128, 128, 128, 0.1);
|
|
13441
|
+
}
|
|
13442
|
+
.retold-remote-topbar-aisort-btn.generating
|
|
13443
|
+
{
|
|
13444
|
+
color: var(--retold-accent);
|
|
13445
|
+
border-color: var(--retold-accent);
|
|
13446
|
+
cursor: wait;
|
|
13447
|
+
}
|
|
13090
13448
|
.retold-remote-topbar-filter-badge
|
|
13091
13449
|
{
|
|
13092
13450
|
position: absolute;
|
|
@@ -13110,6 +13468,7 @@ if(tmpRemote._distractionFreeMode){let tmpViewerHeader=document.querySelector('.
|
|
|
13110
13468
|
<div class="retold-remote-topbar-location" id="RetoldRemote-TopBar-Location"></div>
|
|
13111
13469
|
<div class="retold-remote-topbar-info" id="RetoldRemote-TopBar-Info"></div>
|
|
13112
13470
|
<div class="retold-remote-topbar-actions">
|
|
13471
|
+
<button class="retold-remote-topbar-aisort-btn" id="RetoldRemote-TopBar-AISortBtn" onclick="pict.views['ContentEditor-TopBar'].triggerAISort()" title="AI Sort (generate sort plan for current folder)" style="display:none;">AI Sort</button>
|
|
13113
13472
|
<button class="retold-remote-topbar-btn retold-remote-topbar-addcoll-btn" id="RetoldRemote-TopBar-AddToCollectionBtn" onclick="pict.views['ContentEditor-TopBar'].addToCollection(event)" title="Add to collection">+★</button>
|
|
13114
13473
|
<button class="retold-remote-topbar-sidebar-toggle retold-remote-topbar-collections-btn" id="RetoldRemote-TopBar-CollectionsBtn" onclick="pict.views['ContentEditor-TopBar'].toggleCollections()" title="Toggle Collections panel (b)">★</button>
|
|
13115
13474
|
<button class="retold-remote-topbar-filter-btn" id="RetoldRemote-TopBar-FilterBtn" onclick="pict.views['ContentEditor-TopBar'].toggleFilterBar()" title="Toggle filter bar (/)">◢</button>
|
|
@@ -13160,7 +13519,16 @@ tmpBtn.classList.add('filter-active');tmpBtn.innerHTML='◓<span class="reto
|
|
|
13160
13519
|
tmpBtn.classList.add('filter-bar-open');tmpBtn.innerHTML='◢';tmpBtn.title='Hide filter bar (/)';}else{// Default: no filters, bar hidden
|
|
13161
13520
|
tmpBtn.innerHTML='◢';tmpBtn.title='Toggle filter bar (/)';}}/**
|
|
13162
13521
|
* Update the info display with folder summary.
|
|
13163
|
-
|
|
13522
|
+
* Also updates the AI Sort button visibility.
|
|
13523
|
+
*/updateInfo(){this.updateAISortButton();let tmpInfoEl=document.getElementById('RetoldRemote-TopBar-Info');if(!tmpInfoEl){return;}let tmpRemote=this.pict.AppData.RetoldRemote;let tmpSummary=tmpRemote.FolderSummary;if(tmpRemote.ActiveMode==='viewer'){let tmpItems=tmpRemote.GalleryItems||[];let tmpIndex=tmpRemote.GalleryCursorIndex||0;let tmpItem=tmpItems[tmpIndex];if(tmpItem){let tmpPos=tmpIndex+1+'/'+tmpItems.length;tmpInfoEl.textContent=tmpPos+' \u00b7 '+tmpItem.Name;}return;}let tmpItems=tmpRemote.GalleryItems||[];let tmpIndex=tmpRemote.GalleryCursorIndex||0;let tmpCursorText='';if(tmpItems.length>0){tmpCursorText=tmpIndex+1+'/'+tmpItems.length;}if(!tmpSummary){tmpInfoEl.textContent=tmpCursorText;return;}let tmpParts=[];if(tmpCursorText)tmpParts.push(tmpCursorText);if(tmpSummary.Folders>0)tmpParts.push(tmpSummary.Folders+' folders');if(tmpSummary.Images>0)tmpParts.push(tmpSummary.Images+' images');if(tmpSummary.Videos>0)tmpParts.push(tmpSummary.Videos+' videos');if(tmpSummary.Audio>0)tmpParts.push(tmpSummary.Audio+' audio');if(tmpSummary.Documents>0)tmpParts.push(tmpSummary.Documents+' docs');if(tmpSummary.Other>0)tmpParts.push(tmpSummary.Other+' other');tmpInfoEl.textContent=tmpParts.join(' \u00b7 ');}// -- AI Sort ----------------------------------------------------------
|
|
13524
|
+
/**
|
|
13525
|
+
* Trigger AI sort for the current folder.
|
|
13526
|
+
*/triggerAISort(){let tmpAISortManager=this.pict.providers['RetoldRemote-AISortManager'];if(!tmpAISortManager){return;}let tmpCurrentPath=this.pict.AppData.PictFileBrowser&&this.pict.AppData.PictFileBrowser.CurrentLocation||'';// Show generating state
|
|
13527
|
+
let tmpBtn=document.getElementById('RetoldRemote-TopBar-AISortBtn');if(tmpBtn){tmpBtn.classList.add('generating');tmpBtn.textContent='Sorting...';}tmpAISortManager.generateSortPlan(tmpCurrentPath,(pError,pResult)=>{// Reset button state
|
|
13528
|
+
if(tmpBtn){tmpBtn.classList.remove('generating');tmpBtn.textContent='AI Sort';}});}/**
|
|
13529
|
+
* Update the AI Sort button visibility.
|
|
13530
|
+
* Shows only when browsing a folder (gallery mode).
|
|
13531
|
+
*/updateAISortButton(){let tmpBtn=document.getElementById('RetoldRemote-TopBar-AISortBtn');if(!tmpBtn){return;}let tmpAISortManager=this.pict.providers['RetoldRemote-AISortManager'];if(tmpAISortManager&&tmpAISortManager.isAvailable()){tmpBtn.style.display='';}else{tmpBtn.style.display='none';}}// -- Collections Panel ------------------------------------------------
|
|
13164
13532
|
/**
|
|
13165
13533
|
* Toggle the collections panel.
|
|
13166
13534
|
*/toggleCollections(){let tmpManager=this.pict.providers['RetoldRemote-CollectionManager'];if(tmpManager){tmpManager.togglePanel();}}/**
|
|
@@ -13185,7 +13553,7 @@ for(let i=0;i<tmpCollections.length;i++){let tmpCollection=tmpCollections[i];let
|
|
|
13185
13553
|
tmpBtn.style.position='relative';tmpBtn.appendChild(tmpDropdown);// Close on outside click
|
|
13186
13554
|
setTimeout(()=>{document.addEventListener('click',tmpSelf._boundCloseDropdown=pClickEvent=>{if(!tmpDropdown.contains(pClickEvent.target)&&pClickEvent.target!==tmpBtn){tmpSelf._closeAddToCollectionDropdown();}});},10);});}/**
|
|
13187
13555
|
* Close the add-to-collection dropdown.
|
|
13188
|
-
*/_closeAddToCollectionDropdown(){let tmpDropdown=document.getElementById('RetoldRemote-AddToCollection-Dropdown');if(tmpDropdown){tmpDropdown.remove();}if(this._boundCloseDropdown){document.removeEventListener('click',this._boundCloseDropdown);this._boundCloseDropdown=null;}}}RetoldRemoteTopBarView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteTopBarView;},{"pict-view":76}],
|
|
13556
|
+
*/_closeAddToCollectionDropdown(){let tmpDropdown=document.getElementById('RetoldRemote-AddToCollection-Dropdown');if(tmpDropdown){tmpDropdown.remove();}if(this._boundCloseDropdown){document.removeEventListener('click',this._boundCloseDropdown);this._boundCloseDropdown=null;}}}RetoldRemoteTopBarView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteTopBarView;},{"pict-view":76}],137:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"RetoldRemote-VLCSetup",DefaultRenderable:"RetoldRemote-VLCSetup",DefaultDestinationAddress:"#ContentEditor-Application-Container",AutoRender:false,CSS:/*css*/`
|
|
13189
13557
|
.retold-remote-vlc-modal-backdrop
|
|
13190
13558
|
{
|
|
13191
13559
|
position: fixed;
|
|
@@ -13437,7 +13805,7 @@ tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="r
|
|
|
13437
13805
|
tmpHTML+='<div class="retold-remote-vlc-setup-status">';tmpHTML+='<div class="retold-remote-vlc-setup-status-dot '+(this._detectPlatform()===tmpPlatform?'detected':'unknown')+'"></div>';tmpHTML+='<span>Detected platform: <b>'+this._getPlatformLabel(this._detectPlatform())+'</b></span>';tmpHTML+='</div>';// Platform tabs
|
|
13438
13806
|
tmpHTML+='<div class="retold-remote-vlc-setup-platform-tabs">';tmpHTML+=this._buildPlatformTab('macos','macOS',tmpPlatform);tmpHTML+=this._buildPlatformTab('windows','Windows',tmpPlatform);tmpHTML+=this._buildPlatformTab('linux','Linux',tmpPlatform);tmpHTML+='</div>';// Platform-specific content
|
|
13439
13807
|
tmpHTML+=this._buildMacOSContent(tmpPlatform);tmpHTML+=this._buildWindowsContent(tmpPlatform);tmpHTML+=this._buildLinuxContent(tmpPlatform);// Test section
|
|
13440
|
-
tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Test</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='Click below to test whether the vlc:// protocol handler is registered. VLC should open.';tmpHTML+='</div>';tmpHTML+='<button class="retold-remote-vlc-setup-btn" onclick="pict.views[\'RetoldRemote-VLCSetup\'].testProtocol()">Test VLC Protocol</button>';tmpHTML+='</div>';tmpContainer.innerHTML=tmpHTML;}_buildPlatformTab(pKey,pLabel,pActive){let tmpClass='retold-remote-vlc-setup-platform-tab';if(pKey===pActive){tmpClass+=' active';}return'<button class="'+tmpClass+'" onclick="pict.views[\'RetoldRemote-VLCSetup\'].switchPlatformTab(\''+pKey+'\')">'+pLabel+'</button>';}_getPlatformLabel(pKey){if(pKey==='macos')return'macOS';if(pKey==='windows')return'Windows';return'Linux';}_buildMacOSContent(pActive){let tmpClass='retold-remote-vlc-setup-platform'+(pActive==='macos'?' active':'');let tmpHTML='<div class="'+tmpClass+'" data-platform="macos">';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Setup (macOS)</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='VLC on macOS does not register a vlc:// protocol handler by default. ';tmpHTML+='An AppleScript app bundle is needed to bridge vlc:// links to VLC. ';tmpHTML+='Run the command below in Terminal to create and register the handler automatically.';tmpHTML+='</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Automatic Setup</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='Copy and paste this into Terminal:';tmpHTML+='</div>';let tmpScript=this._getMacSetupScript();tmpHTML+='<div class="retold-remote-vlc-setup-code">'+this.pict.providers['RetoldRemote-FormattingUtilities'].escapeHTML(tmpScript)+'</div>';tmpHTML+='<button class="retold-remote-vlc-setup-btn primary" onclick="pict.views[\'RetoldRemote-VLCSetup\'].copyMacSetup()">Copy to Clipboard</button>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">What This Does</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">1</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Creates an AppleScript at <code>/tmp/VLCProtocol.applescript</code> that handles vlc:// URLs</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">2</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Compiles it into an app bundle at <code>/Applications/VLCProtocol.app</code></div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">3</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Adds the vlc:// URL scheme to the app\'s Info.plist</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">4</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Registers the protocol handler with macOS Launch Services</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-note">Requires VLC installed at /Applications/VLC.app and Python 3 (included with macOS).</div>';tmpHTML+='</div>';tmpHTML+='</div>';return tmpHTML;}_buildWindowsContent(pActive){let tmpClass='retold-remote-vlc-setup-platform'+(pActive==='windows'?' active':'');let tmpHTML='<div class="'+tmpClass+'" data-platform="windows">';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Setup (Windows)</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='VLC on Windows registers the vlc:// protocol handler during installation. ';tmpHTML+='If it is not working, you can re-register it by saving and running the registry file below.';tmpHTML+='</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Option A: Reinstall VLC</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">1</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Reinstall VLC and ensure "Register VLC as handler for vlc:// protocol" is checked during installation.</div>';tmpHTML+='</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Option B: Registry File</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='Save this as <code>vlc-protocol.reg</code> and double-click to import. ';tmpHTML+='Adjust the VLC path if yours differs.';tmpHTML+='</div>';let tmpRegFile=this._getWindowsRegFile();tmpHTML+='<div class="retold-remote-vlc-setup-code">'+this.pict.providers['RetoldRemote-FormattingUtilities'].escapeHTML(tmpRegFile)+'</div>';tmpHTML+='<button class="retold-remote-vlc-setup-btn primary" onclick="pict.views[\'RetoldRemote-VLCSetup\'].copyWindowsReg()">Copy to Clipboard</button>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Option C: Batch Script</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='Alternatively, save this as <code>vlc-protocol-setup.bat</code> and run as Administrator. ';tmpHTML+='This creates a wrapper script that URL-decodes the vlc:// link before passing it to VLC.';tmpHTML+='</div>';let tmpBatchScript=this._getWindowsBatchScript();tmpHTML+='<div class="retold-remote-vlc-setup-code">'+this.pict.providers['RetoldRemote-FormattingUtilities'].escapeHTML(tmpBatchScript)+'</div>';tmpHTML+='<button class="retold-remote-vlc-setup-btn primary" onclick="pict.views[\'RetoldRemote-VLCSetup\'].copyWindowsBatch()">Copy to Clipboard</button>';tmpHTML+='</div>';tmpHTML+='</div>';return tmpHTML;}_buildLinuxContent(pActive){let tmpClass='retold-remote-vlc-setup-platform'+(pActive==='linux'?' active':'');let tmpHTML='<div class="'+tmpClass+'" data-platform="linux">';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Setup (Linux)</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='Register a vlc:// protocol handler using a .desktop file and xdg-mime. ';tmpHTML+='Run the command below in a terminal.';tmpHTML+='</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Setup Command</div>';let tmpScript=this._getLinuxSetupScript();tmpHTML+='<div class="retold-remote-vlc-setup-code">'+this.pict.providers['RetoldRemote-FormattingUtilities'].escapeHTML(tmpScript)+'</div>';tmpHTML+='<button class="retold-remote-vlc-setup-btn primary" onclick="pict.views[\'RetoldRemote-VLCSetup\'].copyLinuxSetup()">Copy to Clipboard</button>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">What This Does</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">1</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Creates a handler script at <code>~/.local/bin/vlc-protocol</code> that URL-decodes and opens VLC</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">2</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Creates a .desktop file at <code>~/.local/share/applications/vlc-protocol.desktop</code></div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">3</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Registers vlc:// as a URL scheme via <code>xdg-mime</code></div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-note">Requires VLC and Python 3 installed.</div>';tmpHTML+='</div>';tmpHTML+='</div>';return tmpHTML;}_getMacSetupScript(){return["# Create the AppleScript handler","cat > /tmp/VLCProtocol.applescript << 'EOF'","on open location theURL","\tset theURL to text 7 thru -1 of theURL","\tset theURL to do shell script \"python3 -c 'import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))' \" & quoted form of theURL","\tdo shell script \"open -a VLC \" & quoted form of theURL","end open location","EOF","","# Compile into app bundle","osacompile -o /Applications/VLCProtocol.app /tmp/VLCProtocol.applescript","","# Add vlc:// URL scheme to Info.plist","/usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes array\" \\"," /Applications/VLCProtocol.app/Contents/Info.plist 2>/dev/null","/usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes:0 dict\" \\"," /Applications/VLCProtocol.app/Contents/Info.plist 2>/dev/null","/usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes:0:CFBundleURLName string 'VLC Protocol'\" \\"," /Applications/VLCProtocol.app/Contents/Info.plist 2>/dev/null","/usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes:0:CFBundleURLSchemes array\" \\"," /Applications/VLCProtocol.app/Contents/Info.plist 2>/dev/null","/usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes:0:CFBundleURLSchemes:0 string vlc\" \\"," /Applications/VLCProtocol.app/Contents/Info.plist 2>/dev/null","","# Register with Launch Services","/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister \\"," -f /Applications/VLCProtocol.app","","echo \"VLC protocol handler installed successfully.\""].join('\n');}_getWindowsRegFile(){return["Windows Registry Editor Version 5.00","","[HKEY_CLASSES_ROOT\\vlc]","@=\"URL:VLC Protocol\"","\"URL Protocol\"=\"\"","","[HKEY_CLASSES_ROOT\\vlc\\shell]","","[HKEY_CLASSES_ROOT\\vlc\\shell\\open]","","[HKEY_CLASSES_ROOT\\vlc\\shell\\open\\command]","@=\"\\\"C:\\\\Program Files\\\\VideoLAN\\\\VLC\\\\vlc.exe\\\" \\\"%1\\\"\""].join('\n');}_getWindowsBatchScript(){return["@echo off","REM VLC Protocol Handler Setup for Windows","REM Run this as Administrator","","REM Create the handler script","mkdir \"%APPDATA%\\VLCProtocol\" 2>nul","(","echo import sys, urllib.parse, subprocess","echo url = sys.argv[1] if len(sys.argv^) ^> 1 else ''","echo if url.startswith('vlc://'^): url = url[6:]","echo url = urllib.parse.unquote(url^)","echo subprocess.Popen(['C:\\\\Program Files\\\\VideoLAN\\\\VLC\\\\vlc.exe', url]^)",") > \"%APPDATA%\\VLCProtocol\\handler.py\"","","REM Register the protocol in the registry","reg add \"HKCU\\Software\\Classes\\vlc\" /ve /d \"URL:VLC Protocol\" /f","reg add \"HKCU\\Software\\Classes\\vlc\" /v \"URL Protocol\" /d \"\" /f","reg add \"HKCU\\Software\\Classes\\vlc\\shell\\open\\command\" /ve /d \"pythonw \\\"%APPDATA%\\VLCProtocol\\handler.py\\\" \\\"%%1\\\"\" /f","","echo VLC protocol handler installed successfully.","pause"].join('\n');}_getLinuxSetupScript(){return["# Create handler script","mkdir -p ~/.local/bin","cat > ~/.local/bin/vlc-protocol << 'EOF'","#!/bin/bash","URL=\"$1\"","URL=\"${URL#vlc://}\"","URL=$(python3 -c \"import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))\" \"$URL\")","exec vlc \"$URL\" &","EOF","chmod +x ~/.local/bin/vlc-protocol","","# Create .desktop file","cat > ~/.local/share/applications/vlc-protocol.desktop << 'EOF'","[Desktop Entry]","Name=VLC Protocol Handler","Exec=bash -c '~/.local/bin/vlc-protocol %u'","Type=Application","NoDisplay=true","MimeType=x-scheme-handler/vlc;","EOF","","# Register the handler","xdg-mime default vlc-protocol.desktop x-scheme-handler/vlc","update-desktop-database ~/.local/share/applications/","","echo \"VLC protocol handler installed successfully.\""].join('\n');}_copyToClipboard(pText,pLabel){if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(pText).then(()=>{this.pict.providers['RetoldRemote-ToastNotification'].showToast(pLabel+' copied to clipboard');}).catch(()=>{this._fallbackCopy(pText,pLabel);});}else{this._fallbackCopy(pText,pLabel);}}_fallbackCopy(pText,pLabel){let tmpTextarea=document.createElement('textarea');tmpTextarea.value=pText;tmpTextarea.style.position='fixed';tmpTextarea.style.left='-9999px';document.body.appendChild(tmpTextarea);tmpTextarea.select();try{document.execCommand('copy');this.pict.providers['RetoldRemote-ToastNotification'].showToast(pLabel+' copied to clipboard');}catch(pErr){this.pict.providers['RetoldRemote-ToastNotification'].showToast('Failed to copy - please select and copy manually');}document.body.removeChild(tmpTextarea);}copyMacSetup(){this._copyToClipboard(this._getMacSetupScript(),'macOS setup script');}copyWindowsReg(){this._copyToClipboard(this._getWindowsRegFile(),'Registry file');}copyWindowsBatch(){this._copyToClipboard(this._getWindowsBatchScript(),'Batch script');}copyLinuxSetup(){this._copyToClipboard(this._getLinuxSetupScript(),'Linux setup script');}testProtocol(){let tmpIsWindows=/Windows/.test(navigator.userAgent);let tmpSampleURL='https://www.sample-videos.com/video321/mp4/720/big_buck_bunny_720p_1mb.mp4';let tmpTestURL=tmpIsWindows?'vlc://'+tmpSampleURL:'vlc://'+encodeURIComponent(tmpSampleURL);let tmpLink=document.createElement('a');tmpLink.href=tmpTestURL;tmpLink.style.display='none';document.body.appendChild(tmpLink);tmpLink.click();document.body.removeChild(tmpLink);}}RetoldRemoteVLCSetupView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteVLCSetupView;},{"pict-view":76}],137:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"RetoldRemote-VideoExplorer",DefaultRenderable:"RetoldRemote-VideoExplorer",DefaultDestinationAddress:"#RetoldRemote-Viewer-Container",AutoRender:false,CSS:/*css*/`
|
|
13808
|
+
tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Test</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='Click below to test whether the vlc:// protocol handler is registered. VLC should open.';tmpHTML+='</div>';tmpHTML+='<button class="retold-remote-vlc-setup-btn" onclick="pict.views[\'RetoldRemote-VLCSetup\'].testProtocol()">Test VLC Protocol</button>';tmpHTML+='</div>';tmpContainer.innerHTML=tmpHTML;}_buildPlatformTab(pKey,pLabel,pActive){let tmpClass='retold-remote-vlc-setup-platform-tab';if(pKey===pActive){tmpClass+=' active';}return'<button class="'+tmpClass+'" onclick="pict.views[\'RetoldRemote-VLCSetup\'].switchPlatformTab(\''+pKey+'\')">'+pLabel+'</button>';}_getPlatformLabel(pKey){if(pKey==='macos')return'macOS';if(pKey==='windows')return'Windows';return'Linux';}_buildMacOSContent(pActive){let tmpClass='retold-remote-vlc-setup-platform'+(pActive==='macos'?' active':'');let tmpHTML='<div class="'+tmpClass+'" data-platform="macos">';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Setup (macOS)</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='VLC on macOS does not register a vlc:// protocol handler by default. ';tmpHTML+='An AppleScript app bundle is needed to bridge vlc:// links to VLC. ';tmpHTML+='Run the command below in Terminal to create and register the handler automatically.';tmpHTML+='</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Automatic Setup</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='Copy and paste this into Terminal:';tmpHTML+='</div>';let tmpScript=this._getMacSetupScript();tmpHTML+='<div class="retold-remote-vlc-setup-code">'+this.pict.providers['RetoldRemote-FormattingUtilities'].escapeHTML(tmpScript)+'</div>';tmpHTML+='<button class="retold-remote-vlc-setup-btn primary" onclick="pict.views[\'RetoldRemote-VLCSetup\'].copyMacSetup()">Copy to Clipboard</button>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">What This Does</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">1</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Creates an AppleScript at <code>/tmp/VLCProtocol.applescript</code> that handles vlc:// URLs</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">2</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Compiles it into an app bundle at <code>/Applications/VLCProtocol.app</code></div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">3</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Adds the vlc:// URL scheme to the app\'s Info.plist</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">4</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Registers the protocol handler with macOS Launch Services</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-note">Requires VLC installed at /Applications/VLC.app and Python 3 (included with macOS).</div>';tmpHTML+='</div>';tmpHTML+='</div>';return tmpHTML;}_buildWindowsContent(pActive){let tmpClass='retold-remote-vlc-setup-platform'+(pActive==='windows'?' active':'');let tmpHTML='<div class="'+tmpClass+'" data-platform="windows">';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Setup (Windows)</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='VLC on Windows registers the vlc:// protocol handler during installation. ';tmpHTML+='If it is not working, you can re-register it by saving and running the registry file below.';tmpHTML+='</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Option A: Reinstall VLC</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">1</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Reinstall VLC and ensure "Register VLC as handler for vlc:// protocol" is checked during installation.</div>';tmpHTML+='</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Option B: Registry File</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='Save this as <code>vlc-protocol.reg</code> and double-click to import. ';tmpHTML+='Adjust the VLC path if yours differs.';tmpHTML+='</div>';let tmpRegFile=this._getWindowsRegFile();tmpHTML+='<div class="retold-remote-vlc-setup-code">'+this.pict.providers['RetoldRemote-FormattingUtilities'].escapeHTML(tmpRegFile)+'</div>';tmpHTML+='<button class="retold-remote-vlc-setup-btn primary" onclick="pict.views[\'RetoldRemote-VLCSetup\'].copyWindowsReg()">Copy to Clipboard</button>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Option C: Batch Script</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='Alternatively, save this as <code>vlc-protocol-setup.bat</code> and run as Administrator. ';tmpHTML+='This creates a wrapper script that URL-decodes the vlc:// link before passing it to VLC.';tmpHTML+='</div>';let tmpBatchScript=this._getWindowsBatchScript();tmpHTML+='<div class="retold-remote-vlc-setup-code">'+this.pict.providers['RetoldRemote-FormattingUtilities'].escapeHTML(tmpBatchScript)+'</div>';tmpHTML+='<button class="retold-remote-vlc-setup-btn primary" onclick="pict.views[\'RetoldRemote-VLCSetup\'].copyWindowsBatch()">Copy to Clipboard</button>';tmpHTML+='</div>';tmpHTML+='</div>';return tmpHTML;}_buildLinuxContent(pActive){let tmpClass='retold-remote-vlc-setup-platform'+(pActive==='linux'?' active':'');let tmpHTML='<div class="'+tmpClass+'" data-platform="linux">';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Setup (Linux)</div>';tmpHTML+='<div class="retold-remote-vlc-setup-desc">';tmpHTML+='Register a vlc:// protocol handler using a .desktop file and xdg-mime. ';tmpHTML+='Run the command below in a terminal.';tmpHTML+='</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">Setup Command</div>';let tmpScript=this._getLinuxSetupScript();tmpHTML+='<div class="retold-remote-vlc-setup-code">'+this.pict.providers['RetoldRemote-FormattingUtilities'].escapeHTML(tmpScript)+'</div>';tmpHTML+='<button class="retold-remote-vlc-setup-btn primary" onclick="pict.views[\'RetoldRemote-VLCSetup\'].copyLinuxSetup()">Copy to Clipboard</button>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-section">';tmpHTML+='<div class="retold-remote-vlc-setup-section-title">What This Does</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">1</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Creates a handler script at <code>~/.local/bin/vlc-protocol</code> that URL-decodes and opens VLC</div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">2</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Creates a .desktop file at <code>~/.local/share/applications/vlc-protocol.desktop</code></div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step">';tmpHTML+='<div class="retold-remote-vlc-setup-step-num">3</div>';tmpHTML+='<div class="retold-remote-vlc-setup-step-content">Registers vlc:// as a URL scheme via <code>xdg-mime</code></div>';tmpHTML+='</div>';tmpHTML+='<div class="retold-remote-vlc-setup-note">Requires VLC and Python 3 installed.</div>';tmpHTML+='</div>';tmpHTML+='</div>';return tmpHTML;}_getMacSetupScript(){return["# Create the AppleScript handler","cat > /tmp/VLCProtocol.applescript << 'EOF'","on open location theURL","\tset theURL to text 7 thru -1 of theURL","\tset theURL to do shell script \"python3 -c 'import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))' \" & quoted form of theURL","\tdo shell script \"open -a VLC \" & quoted form of theURL","end open location","EOF","","# Compile into app bundle","osacompile -o /Applications/VLCProtocol.app /tmp/VLCProtocol.applescript","","# Add vlc:// URL scheme to Info.plist","/usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes array\" \\"," /Applications/VLCProtocol.app/Contents/Info.plist 2>/dev/null","/usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes:0 dict\" \\"," /Applications/VLCProtocol.app/Contents/Info.plist 2>/dev/null","/usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes:0:CFBundleURLName string 'VLC Protocol'\" \\"," /Applications/VLCProtocol.app/Contents/Info.plist 2>/dev/null","/usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes:0:CFBundleURLSchemes array\" \\"," /Applications/VLCProtocol.app/Contents/Info.plist 2>/dev/null","/usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes:0:CFBundleURLSchemes:0 string vlc\" \\"," /Applications/VLCProtocol.app/Contents/Info.plist 2>/dev/null","","# Register with Launch Services","/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister \\"," -f /Applications/VLCProtocol.app","","echo \"VLC protocol handler installed successfully.\""].join('\n');}_getWindowsRegFile(){return["Windows Registry Editor Version 5.00","","[HKEY_CLASSES_ROOT\\vlc]","@=\"URL:VLC Protocol\"","\"URL Protocol\"=\"\"","","[HKEY_CLASSES_ROOT\\vlc\\shell]","","[HKEY_CLASSES_ROOT\\vlc\\shell\\open]","","[HKEY_CLASSES_ROOT\\vlc\\shell\\open\\command]","@=\"\\\"C:\\\\Program Files\\\\VideoLAN\\\\VLC\\\\vlc.exe\\\" \\\"%1\\\"\""].join('\n');}_getWindowsBatchScript(){return["@echo off","REM VLC Protocol Handler Setup for Windows","REM Run this as Administrator","","REM Create the handler script","mkdir \"%APPDATA%\\VLCProtocol\" 2>nul","(","echo import sys, urllib.parse, subprocess","echo url = sys.argv[1] if len(sys.argv^) ^> 1 else ''","echo if url.startswith('vlc://'^): url = url[6:]","echo url = urllib.parse.unquote(url^)","echo subprocess.Popen(['C:\\\\Program Files\\\\VideoLAN\\\\VLC\\\\vlc.exe', url]^)",") > \"%APPDATA%\\VLCProtocol\\handler.py\"","","REM Register the protocol in the registry","reg add \"HKCU\\Software\\Classes\\vlc\" /ve /d \"URL:VLC Protocol\" /f","reg add \"HKCU\\Software\\Classes\\vlc\" /v \"URL Protocol\" /d \"\" /f","reg add \"HKCU\\Software\\Classes\\vlc\\shell\\open\\command\" /ve /d \"pythonw \\\"%APPDATA%\\VLCProtocol\\handler.py\\\" \\\"%%1\\\"\" /f","","echo VLC protocol handler installed successfully.","pause"].join('\n');}_getLinuxSetupScript(){return["# Create handler script","mkdir -p ~/.local/bin","cat > ~/.local/bin/vlc-protocol << 'EOF'","#!/bin/bash","URL=\"$1\"","URL=\"${URL#vlc://}\"","URL=$(python3 -c \"import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))\" \"$URL\")","exec vlc \"$URL\" &","EOF","chmod +x ~/.local/bin/vlc-protocol","","# Create .desktop file","cat > ~/.local/share/applications/vlc-protocol.desktop << 'EOF'","[Desktop Entry]","Name=VLC Protocol Handler","Exec=bash -c '~/.local/bin/vlc-protocol %u'","Type=Application","NoDisplay=true","MimeType=x-scheme-handler/vlc;","EOF","","# Register the handler","xdg-mime default vlc-protocol.desktop x-scheme-handler/vlc","update-desktop-database ~/.local/share/applications/","","echo \"VLC protocol handler installed successfully.\""].join('\n');}_copyToClipboard(pText,pLabel){if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(pText).then(()=>{this.pict.providers['RetoldRemote-ToastNotification'].showToast(pLabel+' copied to clipboard');}).catch(()=>{this._fallbackCopy(pText,pLabel);});}else{this._fallbackCopy(pText,pLabel);}}_fallbackCopy(pText,pLabel){let tmpTextarea=document.createElement('textarea');tmpTextarea.value=pText;tmpTextarea.style.position='fixed';tmpTextarea.style.left='-9999px';document.body.appendChild(tmpTextarea);tmpTextarea.select();try{document.execCommand('copy');this.pict.providers['RetoldRemote-ToastNotification'].showToast(pLabel+' copied to clipboard');}catch(pErr){this.pict.providers['RetoldRemote-ToastNotification'].showToast('Failed to copy - please select and copy manually');}document.body.removeChild(tmpTextarea);}copyMacSetup(){this._copyToClipboard(this._getMacSetupScript(),'macOS setup script');}copyWindowsReg(){this._copyToClipboard(this._getWindowsRegFile(),'Registry file');}copyWindowsBatch(){this._copyToClipboard(this._getWindowsBatchScript(),'Batch script');}copyLinuxSetup(){this._copyToClipboard(this._getLinuxSetupScript(),'Linux setup script');}testProtocol(){let tmpIsWindows=/Windows/.test(navigator.userAgent);let tmpSampleURL='https://www.sample-videos.com/video321/mp4/720/big_buck_bunny_720p_1mb.mp4';let tmpTestURL=tmpIsWindows?'vlc://'+tmpSampleURL:'vlc://'+encodeURIComponent(tmpSampleURL);let tmpLink=document.createElement('a');tmpLink.href=tmpTestURL;tmpLink.style.display='none';document.body.appendChild(tmpLink);tmpLink.click();document.body.removeChild(tmpLink);}}RetoldRemoteVLCSetupView.default_configuration=_ViewConfiguration;module.exports=RetoldRemoteVLCSetupView;},{"pict-view":76}],138:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"RetoldRemote-VideoExplorer",DefaultRenderable:"RetoldRemote-VideoExplorer",DefaultDestinationAddress:"#RetoldRemote-Viewer-Container",AutoRender:false,CSS:/*css*/`
|
|
13441
13809
|
.retold-remote-vex
|
|
13442
13810
|
{
|
|
13443
13811
|
display: flex;
|