mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Refactored organization dialog as a component
This commit is contained in:
parent
4ed019b32d
commit
7835a9d3e6
7 changed files with 718 additions and 119 deletions
|
@ -1,11 +1,11 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/metadataeditor.css">
|
||||||
<title>${TitleAutoOrganize}</title>
|
<title>${TitleAutoOrganize}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="libraryFileOrganizerLogPage" data-role="page" class="page type-interior organizePage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Auto-Organize" data-require="jqmtable,jqmpopup,scripts/autoorganizelog,scripts/taskbutton,detailtablecss,paper-input,paper-checkbox">
|
<div id="libraryFileOrganizerLogPage" data-role="page" class="page type-interior organizePage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Auto-Organize" data-require="jqmtable,jqmpopup,scripts/autoorganizelog,scripts/taskbutton,detailtablecss">
|
||||||
|
|
||||||
<div data-role="content">
|
<div data-role="content">
|
||||||
<div class="content-primary">
|
<div class="content-primary">
|
||||||
|
|
||||||
|
@ -52,48 +52,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-role="popup" class="popup episodeCorrectionPopup">
|
|
||||||
|
|
||||||
<div class="ui-bar-a" style="text-align: center; padding: 0 1em;">
|
|
||||||
<h3>${HeaderEpisodeOrganization}</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div data-role="content">
|
|
||||||
<form class="episodeCorrectionForm" style="padding:0 .5em;">
|
|
||||||
|
|
||||||
<p><span class="inputFile"></span></p>
|
|
||||||
|
|
||||||
<div style="margin: 1em 0 1em; min-width: 250px;">
|
|
||||||
<label for="selectSeries" class="selectLabel">${LabelSeries}</label>
|
|
||||||
<select id="selectSeries" data-mini="true" required="required"></select>
|
|
||||||
</div>
|
|
||||||
<div style="margin: 1em 0;">
|
|
||||||
<paper-input id="txtSeason" type="number" pattern="[0-9]*" required min="0" label="${LabelSeasonNumber}"></paper-input>
|
|
||||||
</div>
|
|
||||||
<div style="margin: 1em 0;">
|
|
||||||
<paper-input id="txtEpisode" type="number" pattern="[0-9]*" required min="0" label="${LabelEpisodeNumber}"></paper-input>
|
|
||||||
</div>
|
|
||||||
<div style="margin: 1em 0;">
|
|
||||||
<paper-input id="txtEndingEpisode" type="number" pattern="[0-9]*" min="0" label="${LabelEndingEpisodeNumber}"></paper-input>
|
|
||||||
<div class="fieldDescription">${LabelEndingEpisodeNumberHelp}</div>
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
<div>
|
|
||||||
<paper-checkbox type="checkbox" id="chkRememberCorrection">${OptionRememberOrganizeCorrection}</paper-checkbox>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
<button type="submit" data-theme="b" data-icon="check" data-mini="true">
|
|
||||||
${ButtonOk}
|
|
||||||
</button>
|
|
||||||
<button type="button" data-icon="delete" onclick="$(this).parents('.popup').popup('close');" data-mini="true">
|
|
||||||
${ButtonCancel}
|
|
||||||
</button>
|
|
||||||
<input id="hfResultId" type="hidden" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1127,6 +1127,39 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.performMovieOrganization = function (id, options) {
|
||||||
|
|
||||||
|
var url = self.getUrl("Library/FileOrganizations/" + id + "/Movie/Organize", options || {});
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.getSmartMatchInfos = function (options) {
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
var url = self.getUrl("Library/FileOrganizationSmartMatch", options);
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: url,
|
||||||
|
dataType: "json"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.deleteSmartMatchEntry = function (id, options) {
|
||||||
|
|
||||||
|
var url = self.getUrl("Library/FileOrganizationSmartMatch/" + id + "/Delete", options || {});
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
self.getLiveTvSeriesTimer = function (id) {
|
self.getLiveTvSeriesTimer = function (id) {
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
|
|
501
dashboard-ui/components/fileorganizer/fileorganizer.js
Normal file
501
dashboard-ui/components/fileorganizer/fileorganizer.js
Normal file
|
@ -0,0 +1,501 @@
|
||||||
|
define(['paperdialoghelper', 'paper-tabs', 'paper-item', 'paper-input', 'paper-fab', 'paper-item-body'], function (paperDialogHelper) {
|
||||||
|
|
||||||
|
var currentItemId;
|
||||||
|
var currentFile;
|
||||||
|
var currentDeferred;
|
||||||
|
var hasChanges = false;
|
||||||
|
var reloadItems;
|
||||||
|
|
||||||
|
function submitEpisodeForm(form) {
|
||||||
|
|
||||||
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
|
var resultId = $('#hfResultId', form).val();
|
||||||
|
|
||||||
|
var targetFolder = $('#spanTargetFolder', form).text();
|
||||||
|
|
||||||
|
var elemString = $('#hfNewSeriesProviderIds', form).val();
|
||||||
|
var newSeriesName = $('#hfNewSeriesName', form).val();
|
||||||
|
var newSeriesYear = $('#hfNewSeriesYear', form).val();
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
|
||||||
|
SeriesId: $('#selectSeries', form).val(),
|
||||||
|
SeasonNumber: $('#txtSeason', form).val(),
|
||||||
|
EpisodeNumber: $('#txtEpisode', form).val(),
|
||||||
|
EndingEpisodeNumber: $('#txtEndingEpisode', form).val(),
|
||||||
|
RememberCorrection: $('#chkRememberCorrection', form).checked(),
|
||||||
|
NewSeriesProviderIds: elemString,
|
||||||
|
NewSeriesName: newSeriesName,
|
||||||
|
NewSeriesYear: newSeriesYear,
|
||||||
|
TargetFolder: targetFolder
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiClient.performEpisodeOrganization(resultId, options).then(function () {
|
||||||
|
|
||||||
|
Dashboard.hideLoadingMsg();
|
||||||
|
|
||||||
|
document.querySelector('.organizerDialog').close();
|
||||||
|
|
||||||
|
reloadItems();
|
||||||
|
|
||||||
|
}, onApiFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitMovieForm(form) {
|
||||||
|
|
||||||
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
|
var resultId = $('#hfResultIdMovie', form).val();
|
||||||
|
|
||||||
|
var targetFolder = $('#selectMovieFolder', form).val();
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
MovieName: $('#txtMovieName', form).val(),
|
||||||
|
MovieYear: $('#txtMovieYear', form).val(),
|
||||||
|
TargetFolder: targetFolder
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiClient.performMovieOrganization(resultId, options).then(function () {
|
||||||
|
|
||||||
|
Dashboard.hideLoadingMsg();
|
||||||
|
|
||||||
|
document.querySelector('.organizerDialog').close();
|
||||||
|
|
||||||
|
reloadItems();
|
||||||
|
|
||||||
|
}, onApiFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchForIdentificationResults(popup, itemtype) {
|
||||||
|
|
||||||
|
var lookupInfo = {
|
||||||
|
Name: $('#txtMovieName', popup).val(),
|
||||||
|
Year: $('#txtMovieYear', popup).val(),
|
||||||
|
};
|
||||||
|
|
||||||
|
var url = ApiClient.getUrl("Items/RemoteSearch/Movie");
|
||||||
|
|
||||||
|
if (itemtype == 'tvshows') {
|
||||||
|
lookupInfo.Name = $('#txtNewSeriesName', popup).val();
|
||||||
|
lookupInfo.Year = $('#txtNewSeriesYear', popup).val();
|
||||||
|
url = ApiClient.getUrl("Items/RemoteSearch/Series");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lookupInfo.Name) {
|
||||||
|
Dashboard.alert(Globalize.translate('MessagePleaseEnterNameOrId'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lookupInfo = {
|
||||||
|
SearchInfo: lookupInfo,
|
||||||
|
IncludeDisabledProviders: true
|
||||||
|
};
|
||||||
|
|
||||||
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
|
ApiClient.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: url,
|
||||||
|
data: JSON.stringify(lookupInfo),
|
||||||
|
dataType: "json",
|
||||||
|
contentType: "application/json"
|
||||||
|
|
||||||
|
}).then(function (results) {
|
||||||
|
|
||||||
|
Dashboard.hideLoadingMsg();
|
||||||
|
showIdentificationSearchResults(popup, results, itemtype);
|
||||||
|
|
||||||
|
$('#btnBack', popup).off('click').on('click', function () {
|
||||||
|
$('.identificationResultForm', popup).hide();
|
||||||
|
$('.organizeMovieForm', popup).show();
|
||||||
|
$('.createSeriesForm', popup).show();
|
||||||
|
|
||||||
|
if (itemtype == 'tvshows') {
|
||||||
|
$('#btnBack', popup).off('click').on('click', function () {
|
||||||
|
$('.createSeriesForm', popup).hide();
|
||||||
|
$('.episodeCorrectionForm', popup).show();
|
||||||
|
|
||||||
|
$('#btnBack', popup).off('click').on('click', function () {
|
||||||
|
popup.close();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#btnBack', popup).off('click').on('click', function () {
|
||||||
|
popup.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}, onApiFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showIdentificationSearchResults(popup, results, itemtype) {
|
||||||
|
|
||||||
|
$('.organizeMovieForm', popup).hide();
|
||||||
|
$('.createSeriesForm', popup).hide();
|
||||||
|
$('.identificationResultForm', popup).show();
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
|
||||||
|
for (var i = 0, length = results.length; i < length; i++) {
|
||||||
|
|
||||||
|
var result = results[i];
|
||||||
|
|
||||||
|
html += getIdentifyResultHtml(result, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
var elem = $('.identificationSearchResultList', popup).html(html).trigger('create');
|
||||||
|
|
||||||
|
$('.searchImage', elem).on('click', function () {
|
||||||
|
|
||||||
|
var index = parseInt(this.getAttribute('data-index'));
|
||||||
|
|
||||||
|
var currentResult = results[index];
|
||||||
|
|
||||||
|
$('.identificationResultForm', popup).hide();
|
||||||
|
|
||||||
|
var targetName = currentResult.Name;
|
||||||
|
if (currentResult.ProductionYear) {
|
||||||
|
targetName = targetName + ' (' + currentResult.ProductionYear + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemtype == 'tvshows') {
|
||||||
|
$('#txtNewSeriesName', popup).val(currentResult.Name);
|
||||||
|
$('#txtNewSeriesYear', popup).val(currentResult.ProductionYear);
|
||||||
|
$('#txtSelectedNewSeries', popup).val(targetName);
|
||||||
|
$('#txtSelectedNewSeries2', popup).val(targetName);
|
||||||
|
$('#hfNewSeriesName', popup).val(currentResult.Name);
|
||||||
|
$('#hfNewSeriesYear', popup).val(currentResult.ProductionYear);
|
||||||
|
var elems = currentResult.ProviderIds;
|
||||||
|
$('#hfNewSeriesProviderIds', popup).val(JSON.stringify(elems));
|
||||||
|
$('.createSeriesForm', popup).show();
|
||||||
|
$('#btnBack', popup).off('click').on('click', function () {
|
||||||
|
$('.createSeriesForm', popup).hide();
|
||||||
|
$('.episodeCorrectionForm', popup).show();
|
||||||
|
$('#btnBack', popup).off('click').on('click', function () {
|
||||||
|
popup.close();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#txtMovieName', popup).val(currentResult.Name);
|
||||||
|
$('#txtMovieYear', popup).val(currentResult.ProductionYear);
|
||||||
|
$('#txtSelectedMovie', popup).val(targetName);
|
||||||
|
$('.organizeMovieForm', popup).show();
|
||||||
|
$('#btnBack', popup).off('click').on('click', function () {
|
||||||
|
popup.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSearchImageDisplayUrl(url, provider) {
|
||||||
|
return ApiClient.getUrl("Items/RemoteSearch/Image", { imageUrl: url, ProviderName: provider });
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIdentifyResultHtml(result, index) {
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
var cssClass = "searchImageContainer remoteImageContainer";
|
||||||
|
|
||||||
|
cssClass += " searchPosterImageContainer";
|
||||||
|
|
||||||
|
html += '<div class="' + cssClass + '">';
|
||||||
|
|
||||||
|
if (result.ImageUrl) {
|
||||||
|
var displayUrl = getSearchImageDisplayUrl(result.ImageUrl, result.SearchProviderName);
|
||||||
|
|
||||||
|
html += '<a href="#" class="searchImage" data-index="' + index + '" style="background-image:url(\'' + displayUrl + '\');">';
|
||||||
|
} else {
|
||||||
|
|
||||||
|
html += '<a href="#" class="searchImage iconCardImage" data-index="' + index + '"><iron-icon icon="search"></iron-icon>';
|
||||||
|
}
|
||||||
|
html += '</a>';
|
||||||
|
|
||||||
|
html += '<div class="remoteImageDetails" style="background-color: transparent">';
|
||||||
|
html += result.Name;
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
html += '<div class="remoteImageDetails" style="background-color: transparent">';
|
||||||
|
html += result.ProductionYear || ' ';
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
html += '</div>';
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEpisodeCorrectionFormSubmit() {
|
||||||
|
submitEpisodeForm(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onOrganizeMovieFormFormSubmit() {
|
||||||
|
submitMovieForm(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showTab(popup, index) {
|
||||||
|
$('.organizeMovieForm', popup).show();
|
||||||
|
$('.episodeCorrectionForm', popup).show();
|
||||||
|
$('.identificationResultForm', popup).hide();
|
||||||
|
$('.createSeriesForm', popup).hide();
|
||||||
|
$('.popupTabPage', popup).addClass('hide')[index].classList.remove('hide');
|
||||||
|
|
||||||
|
$('#btnBack', popup).off('click').on('click', function () {
|
||||||
|
popup.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function initEditor(popup, item, allSeries, movieLocations, seriesLocations) {
|
||||||
|
|
||||||
|
$('#divNewSeries', popup).hide();
|
||||||
|
|
||||||
|
showTab(popup, 0);
|
||||||
|
|
||||||
|
$('.inputFile', popup).html(item.OriginalFileName);
|
||||||
|
|
||||||
|
$('#txtSeason', popup).val(item.ExtractedSeasonNumber);
|
||||||
|
$('#txtEpisode', popup).val(item.ExtractedEpisodeNumber);
|
||||||
|
$('#txtEndingEpisode', popup).val(item.ExtractedEndingEpisodeNumber);
|
||||||
|
|
||||||
|
$('#chkRememberCorrection', popup).val(false);
|
||||||
|
$('.extractedName', popup).html(item.ExtractedName);
|
||||||
|
|
||||||
|
if (!item.ExtractedName || item.ExtractedName.length < 4) {
|
||||||
|
$('#divRememberCorrection', popup).hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#txtNewSeriesName', popup).val(item.ExtractedName);
|
||||||
|
$('#txtNewSeriesYear', popup).val(item.ExtractedYear);
|
||||||
|
|
||||||
|
$('#hfResultId', popup).val(item.Id);
|
||||||
|
$('#hfResultIdMovie', popup).val(item.Id);
|
||||||
|
$('#hfNewSeriesProviderIds', popup).val(null);
|
||||||
|
$('#hfNewSeriesName', popup).val(null);
|
||||||
|
$('#hfNewSeriesYear', popup).val(null);
|
||||||
|
|
||||||
|
$('#txtSelectedNewSeries', popup).val(null);
|
||||||
|
$('#txtSelectedNewSeries2', popup).val(null);
|
||||||
|
|
||||||
|
$('#txtMovieName', popup).val(item.ExtractedMovieName);
|
||||||
|
$('#txtMovieYear', popup).val(item.ExtractedMovieYear);
|
||||||
|
$('#txtSelectedMovie', popup).val(null);
|
||||||
|
|
||||||
|
var seriesHtml = allSeries.map(function (s) {
|
||||||
|
|
||||||
|
return '<option value="' + s.Id + '">' + s.Name + '</option>';
|
||||||
|
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
seriesHtml = '<option value=""></option>' + seriesHtml;
|
||||||
|
|
||||||
|
$('#selectSeries', popup).html(seriesHtml);
|
||||||
|
|
||||||
|
|
||||||
|
var movieFolderHtml = movieLocations.map(function (s) {
|
||||||
|
return '<option value="' + s.value + '">' + s.display + '</option>';
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
if (movieLocations.length > 1) {
|
||||||
|
movieFolderHtml = '<option value=""></option>' + movieFolderHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
var seriesFolderHtml = seriesLocations.map(function (s) {
|
||||||
|
return '<option value="' + s.value + '">' + s.display + '</option>';
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
if (seriesLocations.length > 1) {
|
||||||
|
seriesFolderHtml = '<option value=""></option>' + seriesFolderHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#selectMovieFolder', popup).html(movieFolderHtml);
|
||||||
|
$('#selectSeriesFolder', popup).html(seriesFolderHtml);
|
||||||
|
|
||||||
|
$('.episodeCorrectionForm').off('submit', onEpisodeCorrectionFormSubmit).on('submit', onEpisodeCorrectionFormSubmit);
|
||||||
|
$('.organizeMovieForm').off('submit', onOrganizeMovieFormFormSubmit).on('submit', onOrganizeMovieFormFormSubmit);
|
||||||
|
|
||||||
|
$('#btnIdentifyMovie', popup).on('click', function () {
|
||||||
|
searchForIdentificationResults(popup, 'movies');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#btnIdentifySeries', popup).on('click', function () {
|
||||||
|
searchForIdentificationResults(popup, 'tvshows');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.txt-readonly', popup).keydown(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#btnNewSeries', popup).on('click', function () {
|
||||||
|
$('.episodeCorrectionForm', popup).hide();
|
||||||
|
$('.createSeriesForm', popup).show();
|
||||||
|
|
||||||
|
$('#btnBack', popup).off('click').on('click', function () {
|
||||||
|
|
||||||
|
$('.createSeriesForm', popup).hide();
|
||||||
|
$('.episodeCorrectionForm', popup).show();
|
||||||
|
|
||||||
|
$('#btnBack', popup).off('click').on('click', function () {
|
||||||
|
popup.close();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.createSeriesForm').off('submit').on('submit', function () {
|
||||||
|
var folder = $('#selectSeriesFolder', popup).val();
|
||||||
|
$('#spanTargetFolder', popup).text(folder);
|
||||||
|
|
||||||
|
$('#divSelectSeries', popup).hide();
|
||||||
|
$('#divNewSeries', popup).show();
|
||||||
|
$('.episodeCorrectionForm', popup).show();
|
||||||
|
$('.createSeriesForm', popup).hide();
|
||||||
|
|
||||||
|
$('#btnBack', popup).off('click').on('click', function () {
|
||||||
|
popup.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showEditor(page, item, allSeries, movieLocations, seriesLocations, reloadDelegate) {
|
||||||
|
|
||||||
|
reloadItems = reloadDelegate;
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', 'components/fileorganizer/fileorganizer.template.html', true);
|
||||||
|
|
||||||
|
xhr.onload = function (e) {
|
||||||
|
|
||||||
|
var template = this.response;
|
||||||
|
|
||||||
|
var dlg = createDialog();
|
||||||
|
dlg.setAttribute('id', 'with-backdrop');
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
//html += '<div class="ui-bar-a" style="text-align: left; padding: 10px 15px; margin: 0">';
|
||||||
|
html += '<h2 class="dialogHeader">';
|
||||||
|
html += '<paper-fab icon="arrow-back" mini class="btnCloseDialog" id="btnBack"></paper-fab>';
|
||||||
|
html += '<div style="display:inline-block;margin-left:.6em;vertical-align:middle;">' + Globalize.translate('FileOrganizeManually') + '</div>';
|
||||||
|
html += '</h2>';
|
||||||
|
//html += '</div>';
|
||||||
|
|
||||||
|
html += '<div style="padding:0; margin: 10px 0px 0px 0px"><paper-tabs hidescrollbuttons selected="0">';
|
||||||
|
html += '<paper-tab id="popupTab1" class="episodeTabButton">TV Episode</paper-tab>';
|
||||||
|
html += '<paper-tab id="popupTab2" class="movieTabButton">Movie</paper-tab>';
|
||||||
|
html += '</paper-tabs></div>'
|
||||||
|
|
||||||
|
html += '<div class="editorContent" style="margin:auto;">';
|
||||||
|
html += Globalize.translateDocument(template);
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
dlg.innerHTML = html;
|
||||||
|
document.body.appendChild(dlg);
|
||||||
|
|
||||||
|
initEditor(dlg, item, allSeries, movieLocations, seriesLocations);
|
||||||
|
|
||||||
|
// Has to be assigned a z-index after the call to .open()
|
||||||
|
$(dlg).on('iron-overlay-closed', onDialogClosed);
|
||||||
|
|
||||||
|
var tabs = dlg.querySelector('paper-tabs');
|
||||||
|
|
||||||
|
$(tabs).on('iron-select', function () {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var selected = this.selected;
|
||||||
|
showTab(dlg, selected);
|
||||||
|
|
||||||
|
//setTimeout(function () {
|
||||||
|
// Events.trigger(self, 'tabchange');
|
||||||
|
//}, 400);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
//.on('tabchange', function () {
|
||||||
|
// var selected = this.selected;
|
||||||
|
|
||||||
|
// showTab(dlg, selected);
|
||||||
|
//});
|
||||||
|
|
||||||
|
dlg.classList.add('organizerDialog');
|
||||||
|
|
||||||
|
paperDialogHelper.open(dlg);
|
||||||
|
//PaperDialogHelper.openWithHash(dlg, 'fileorganizer');
|
||||||
|
//dlg.open();
|
||||||
|
|
||||||
|
$('#btnBack', dlg).on('click', function () {
|
||||||
|
paperDialogHelper.close(dlg);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDialog() {
|
||||||
|
//var dlg = document.createElement('paper-dialog');
|
||||||
|
|
||||||
|
var dlg = paperDialogHelper.createDialog({
|
||||||
|
removeOnClose: true
|
||||||
|
});
|
||||||
|
|
||||||
|
dlg.setAttribute('with-backdrop', 'with-backdrop');
|
||||||
|
dlg.setAttribute('role', 'alertdialog');
|
||||||
|
|
||||||
|
// without this safari will scroll the background instead of the dialog contents
|
||||||
|
// but not needed here since this is already on top of an existing dialog
|
||||||
|
dlg.setAttribute('modal', 'modal');
|
||||||
|
|
||||||
|
dlg.setAttribute('noAutoFocus', 'noAutoFocus');
|
||||||
|
dlg.entryAnimation = 'scale-up-animation';
|
||||||
|
dlg.exitAnimation = 'fade-out-animation';
|
||||||
|
dlg.classList.add('ui-body-a');
|
||||||
|
dlg.classList.add('background-theme-a');
|
||||||
|
dlg.classList.add('smoothScrollY');
|
||||||
|
|
||||||
|
return dlg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onApiFailure(e) {
|
||||||
|
|
||||||
|
Dashboard.hideLoadingMsg();
|
||||||
|
|
||||||
|
document.querySelector('.organizerDialog').close();
|
||||||
|
|
||||||
|
if (e.status == 0) {
|
||||||
|
Dashboard.alert({
|
||||||
|
title: 'Auto-Organize',
|
||||||
|
message: 'The operation is going to take a little longer. The view will be updated on completion.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Dashboard.alert({
|
||||||
|
title: Globalize.translate('AutoOrganizeError'),
|
||||||
|
message: Globalize.translate('ErrorOrganizingFileWithErrorCode', e.getResponseHeader("X-Application-Error-Code"))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDialogClosed() {
|
||||||
|
|
||||||
|
$(this).remove();
|
||||||
|
Dashboard.hideLoadingMsg();
|
||||||
|
currentDeferred.resolveWith(null, [hasChanges]);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.FileOrganizer = {
|
||||||
|
show: function (page, item, allSeries, movieLocations, seriesLocations, reloadDelegate) {
|
||||||
|
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
currentDeferred = deferred;
|
||||||
|
hasChanges = false;
|
||||||
|
|
||||||
|
showEditor(page, item, allSeries, movieLocations, seriesLocations, reloadDelegate);
|
||||||
|
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
|
@ -0,0 +1,120 @@
|
||||||
|
<div class="popupTabPage">
|
||||||
|
<form class="episodeCorrectionForm">
|
||||||
|
<p><span class="inputFile"></span></p>
|
||||||
|
<div class="layout horizontal center-center" style="margin: 1em 0 1em; min-width: 350px;" id="divSelectSeries">
|
||||||
|
<div style="width: 100%;">
|
||||||
|
<label for="selectSeries">${LabelSeries}</label>
|
||||||
|
<select id="selectSeries" data-mini="true"></select>
|
||||||
|
</div>
|
||||||
|
<button type="button" id="btnNewSeries" data-icon="add" data-mini="true" style="width: auto; margin-left: 15px !important; margin-top: 13px !important">
|
||||||
|
New
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0 1em; min-width: 350px; display: none" id="divNewSeries">
|
||||||
|
<label for="txtSelectedNewSeries2">New Series</label>
|
||||||
|
<input id="txtSelectedNewSeries2" class="txt-readonly" disabled />
|
||||||
|
<div class="fieldDescription"><span id="spanTargetFolder"></span></div>
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0;">
|
||||||
|
<label for="txtSeason">${LabelSeasonNumber}</label>
|
||||||
|
<input id="txtSeason" type="number" pattern="[0-9]*" required="required" min="0" />
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0;">
|
||||||
|
<label for="txtEpisode">${LabelEpisodeNumber}</label>
|
||||||
|
<input id="txtEpisode" type="number" pattern="[0-9]*" required="required" min="0" />
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0;">
|
||||||
|
<label for="txtEndingEpisode">${LabelEndingEpisodeNumber}</label>
|
||||||
|
<input id="txtEndingEpisode" type="number" pattern="[0-9]*" min="0" />
|
||||||
|
<div class="fieldDescription">${LabelEndingEpisodeNumberHelp}</div>
|
||||||
|
</div>
|
||||||
|
<div id="divRememberCorrection" style="margin: 1em 0;">
|
||||||
|
<label style="display:block">${TabSmartMatch}</label>
|
||||||
|
<input type="checkbox" id="chkRememberCorrection" name="chkRememberCorrection" data-mini="true" />
|
||||||
|
<label for="chkRememberCorrection" style="max-width: 350px">${LabelOrganizeSmartMatchOption}: <span class="extractedName" style="font-weight: bold; font-style: italic" /></label>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<button type="submit" data-theme="b" data-icon="check" data-mini="true">
|
||||||
|
${ButtonOk}
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
<input id="hfResultId" type="hidden" />
|
||||||
|
<input id="hfNewSeriesProviderIds" type="hidden" />
|
||||||
|
<input id="hfNewSeriesName" type="hidden" />
|
||||||
|
<input id="hfNewSeriesYear" type="hidden" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form class="createSeriesForm">
|
||||||
|
<p><span class="inputFile"></span></p>
|
||||||
|
<div style="margin: 1em 0 1em; min-width: 350px;">
|
||||||
|
<label for="txtNewSeriesName">${LabelSeries}</label>
|
||||||
|
<input id="txtNewSeriesName" required="required" />
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0;">
|
||||||
|
<label for="txtNewSeriesYear">${LabelYear}</label>
|
||||||
|
<input id="txtNewSeriesYear" type="number" pattern="[0-9]*" min="0" />
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0;">
|
||||||
|
<button type="button" data-icon="info" id="btnIdentifySeries" data-mini="true">
|
||||||
|
${ButtonIdentify}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0 1em;">
|
||||||
|
<label for="txtSelectedNewSeries">Selected Series</label>
|
||||||
|
<!-- When setting the disabled attribute, the required checking on submit does not work.
|
||||||
|
Therefore class text-readonly is used instead to prevent keyboard input -->
|
||||||
|
<input id="txtSelectedNewSeries" class="txt-readonly" required="required" />
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0 1em; min-width: 350px;">
|
||||||
|
<label for="selectSeriesFolder">Destination Folder</label>
|
||||||
|
<select id="selectSeriesFolder" data-mini="true" required="required"></select>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<button type="submit" id="btnCreateNewSeries" data-theme="b" data-icon="check" data-mini="true">
|
||||||
|
Create Series
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="popupTabPage hide">
|
||||||
|
<form class="organizeMovieForm">
|
||||||
|
<p><span class="inputFile"></span></p>
|
||||||
|
<div style="margin: 1em 0 1em; min-width: 350px;">
|
||||||
|
<label for="txtMovieName">Movie</label>
|
||||||
|
<input id="txtMovieName" required="required" min="0" />
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0;">
|
||||||
|
<label for="txtMovieYear">Year</label>
|
||||||
|
<input id="txtMovieYear" type="number" pattern="[0-9]*" min="0" />
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0;">
|
||||||
|
<button type="button" data-icon="info" id="btnIdentifyMovie" data-mini="true">
|
||||||
|
${ButtonIdentify}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0 1em;">
|
||||||
|
<label for="txtSelectedMovie">Selected Movie</label>
|
||||||
|
<input id="txtSelectedMovie" class="txt-readonly" required="required" />
|
||||||
|
</div>
|
||||||
|
<div style="margin: 1em 0 1em; min-width: 350px;">
|
||||||
|
<label for="selectMovieFolder">Destination Folder</label>
|
||||||
|
<select id="selectMovieFolder" data-mini="true" required="required"></select>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<button type="submit" data-theme="b" data-icon="check" data-mini="true">
|
||||||
|
${ButtonOk}
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
<input id="hfResultIdMovie" type="hidden" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="identificationResultForm">
|
||||||
|
<form>
|
||||||
|
|
||||||
|
<div class="identificationSearchResults" style="height:auto; min-width: 350px; min-height: 350px;">
|
||||||
|
<div class="identificationSearchResultList"></div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
|
@ -54,41 +54,57 @@
|
||||||
|
|
||||||
Dashboard.showLoadingMsg();
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
|
var seriesItems;
|
||||||
|
|
||||||
ApiClient.getItems(null, {
|
ApiClient.getItems(null, {
|
||||||
recursive: true,
|
recursive: true,
|
||||||
includeItemTypes: 'Series',
|
includeItemTypes: 'Series',
|
||||||
sortBy: 'SortName'
|
sortBy: 'SortName'
|
||||||
|
|
||||||
}).then(function (result) {
|
}).then(function (result) {
|
||||||
Dashboard.hideLoadingMsg();
|
|
||||||
showEpisodeCorrectionPopup(page, item, result.Items);
|
|
||||||
}, onApiFailure);
|
|
||||||
|
|
||||||
|
seriesItems = result.Items;
|
||||||
|
|
||||||
|
ApiClient.getVirtualFolders().then(function (result) {
|
||||||
|
|
||||||
|
Dashboard.hideLoadingMsg();
|
||||||
|
|
||||||
|
var movieLocations = [];
|
||||||
|
var seriesLocations = [];
|
||||||
|
|
||||||
|
for (var n = 0; n < result.length; n++) {
|
||||||
|
|
||||||
|
var virtualFolder = result[n];
|
||||||
|
|
||||||
|
for (var i = 0, length = virtualFolder.Locations.length; i < length; i++) {
|
||||||
|
var location = {
|
||||||
|
value: virtualFolder.Locations[i],
|
||||||
|
display: virtualFolder.Name + ': ' + virtualFolder.Locations[i]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (virtualFolder.CollectionType == 'movies') {
|
||||||
|
movieLocations.push(location);
|
||||||
|
}
|
||||||
|
if (virtualFolder.CollectionType == 'tvshows') {
|
||||||
|
seriesLocations.push(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showEpisodeCorrectionPopup(page, item, seriesItems, movieLocations, seriesLocations);
|
||||||
|
}, onApiFailure);
|
||||||
|
|
||||||
|
}, onApiFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showEpisodeCorrectionPopup(page, item, allSeries) {
|
function showEpisodeCorrectionPopup(page, item, allSeries, movieLocations, seriesLocations) {
|
||||||
|
|
||||||
var popup = $('.episodeCorrectionPopup', page).popup("open");
|
require(['components/fileorganizer/fileorganizer'], function () {
|
||||||
|
|
||||||
$('.inputFile', popup).html(item.OriginalFileName);
|
FileOrganizer.show(page, item, allSeries, movieLocations, seriesLocations, function () {
|
||||||
|
reloadItems(page);
|
||||||
$('#txtSeason', popup).val(item.ExtractedSeasonNumber);
|
});
|
||||||
$('#txtEpisode', popup).val(item.ExtractedEpisodeNumber);
|
});
|
||||||
$('#txtEndingEpisode', popup).val(item.ExtractedEndingEpisodeNumber);
|
|
||||||
|
|
||||||
$('#chkRememberCorrection', popup).val(false);
|
|
||||||
|
|
||||||
$('#hfResultId', popup).val(item.Id);
|
|
||||||
|
|
||||||
var seriesHtml = allSeries.map(function (s) {
|
|
||||||
|
|
||||||
return '<option value="' + s.Id + '">' + s.Name + '</option>';
|
|
||||||
|
|
||||||
}).join('');
|
|
||||||
|
|
||||||
seriesHtml = '<option value=""></option>' + seriesHtml;
|
|
||||||
|
|
||||||
$('#selectSeries', popup).html(seriesHtml);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function organizeFile(page, id) {
|
function organizeFile(page, id) {
|
||||||
|
@ -131,38 +147,9 @@
|
||||||
|
|
||||||
}, onApiFailure);
|
}, onApiFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitEpisodeForm(form) {
|
|
||||||
|
|
||||||
Dashboard.showLoadingMsg();
|
|
||||||
|
|
||||||
var page = $(form).parents('.page');
|
|
||||||
|
|
||||||
var resultId = $('#hfResultId', form).val();
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
|
|
||||||
SeriesId: $('#selectSeries', form).val(),
|
|
||||||
SeasonNumber: $('#txtSeason', form).val(),
|
|
||||||
EpisodeNumber: $('#txtEpisode', form).val(),
|
|
||||||
EndingEpisodeNumber: $('#txtEndingEpisode', form).val(),
|
|
||||||
RememberCorrection: $('#chkRememberCorrection', form).checked()
|
|
||||||
};
|
|
||||||
|
|
||||||
ApiClient.performEpisodeOrganization(resultId, options).then(function () {
|
|
||||||
|
|
||||||
Dashboard.hideLoadingMsg();
|
|
||||||
|
|
||||||
$('.episodeCorrectionPopup', page).popup("close");
|
|
||||||
|
|
||||||
reloadItems(page);
|
|
||||||
|
|
||||||
}, onApiFailure);
|
|
||||||
}
|
|
||||||
|
|
||||||
function reloadItems(page) {
|
function reloadItems(page) {
|
||||||
|
|
||||||
Dashboard.showLoadingMsg();
|
Dashboard.showLoadingMsg();
|
||||||
|
@ -173,7 +160,6 @@
|
||||||
renderResults(page, result);
|
renderResults(page, result);
|
||||||
|
|
||||||
Dashboard.hideLoadingMsg();
|
Dashboard.hideLoadingMsg();
|
||||||
|
|
||||||
}, onApiFailure);
|
}, onApiFailure);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -229,9 +215,9 @@
|
||||||
var status = item.Status;
|
var status = item.Status;
|
||||||
|
|
||||||
if (status == 'SkippedExisting') {
|
if (status == 'SkippedExisting') {
|
||||||
html += '<div style="color:blue;">';
|
html += '<a data-resultid="' + item.Id + '" style="color:blue;" href="#" class="btnShowStatusMessage">';
|
||||||
html += item.OriginalFileName;
|
html += item.OriginalFileName;
|
||||||
html += '</div>';
|
html += '</a>';
|
||||||
}
|
}
|
||||||
else if (status == 'Failure') {
|
else if (status == 'Failure') {
|
||||||
html += '<a data-resultid="' + item.Id + '" style="color:red;" href="#" class="btnShowStatusMessage">';
|
html += '<a data-resultid="' + item.Id + '" style="color:red;" href="#" class="btnShowStatusMessage">';
|
||||||
|
@ -323,14 +309,9 @@
|
||||||
|
|
||||||
var page = $.mobile.activePage;
|
var page = $.mobile.activePage;
|
||||||
|
|
||||||
if (msg.MessageType == "ScheduledTaskEnded") {
|
if ((msg.MessageType == 'ScheduledTaskEnded' && msg.Data.Key == 'AutoOrganize') || msg.MessageType == 'AutoOrganizeUpdate') {
|
||||||
|
|
||||||
var result = msg.Data;
|
reloadItems(page);
|
||||||
|
|
||||||
if (result.Key == 'AutoOrganize') {
|
|
||||||
|
|
||||||
reloadItems(page);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,15 +319,21 @@
|
||||||
|
|
||||||
Dashboard.hideLoadingMsg();
|
Dashboard.hideLoadingMsg();
|
||||||
|
|
||||||
Dashboard.alert({
|
var page = $.mobile.activePage;
|
||||||
title: Globalize.translate('AutoOrganizeError'),
|
$('.episodeCorrectionPopup', page).popup("close");
|
||||||
message: Globalize.translate('ErrorOrganizingFileWithErrorCode', e.getResponseHeader("X-Application-Error-Code"))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEpisodeCorrectionFormSubmit() {
|
if (e.status == 0) {
|
||||||
submitEpisodeForm(this);
|
Dashboard.alert({
|
||||||
return false;
|
title: 'Auto-Organize',
|
||||||
|
message: 'The operation is going to take a little longer. The view will be updated on completion.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Dashboard.alert({
|
||||||
|
title: Globalize.translate('AutoOrganizeError'),
|
||||||
|
message: Globalize.translate('ErrorOrganizingFileWithErrorCode', e.getResponseHeader("X-Application-Error-Code"))
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).on('pageinit', "#libraryFileOrganizerLogPage", function () {
|
$(document).on('pageinit', "#libraryFileOrganizerLogPage", function () {
|
||||||
|
@ -361,8 +348,6 @@
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.episodeCorrectionForm').off('submit', onEpisodeCorrectionFormSubmit).on('submit', onEpisodeCorrectionFormSubmit);
|
|
||||||
|
|
||||||
}).on('pageshow', "#libraryFileOrganizerLogPage", function () {
|
}).on('pageshow', "#libraryFileOrganizerLogPage", function () {
|
||||||
|
|
||||||
var page = this;
|
var page = this;
|
||||||
|
@ -377,7 +362,7 @@
|
||||||
taskKey: 'AutoOrganize'
|
taskKey: 'AutoOrganize'
|
||||||
});
|
});
|
||||||
|
|
||||||
$(ApiClient).on("websocketmessage.autoorganizelog", onWebSocketMessage);
|
Events.on(ApiClient, "websocketmessage", onWebSocketMessage);
|
||||||
|
|
||||||
}).on('pagebeforehide', "#libraryFileOrganizerLogPage", function () {
|
}).on('pagebeforehide', "#libraryFileOrganizerLogPage", function () {
|
||||||
|
|
||||||
|
@ -390,7 +375,7 @@
|
||||||
mode: 'off'
|
mode: 'off'
|
||||||
});
|
});
|
||||||
|
|
||||||
$(ApiClient).off("websocketmessage.autoorganizelog", onWebSocketMessage);
|
Events.off(ApiClient, "websocketmessage", onWebSocketMessage);
|
||||||
});
|
});
|
||||||
|
|
||||||
})(jQuery, document, window);
|
})(jQuery, document, window);
|
||||||
|
|
|
@ -263,6 +263,7 @@
|
||||||
"HeaderSelectWatchFolderHelp": "Browse or enter the path to your watch folder. The folder must be writeable.",
|
"HeaderSelectWatchFolderHelp": "Browse or enter the path to your watch folder. The folder must be writeable.",
|
||||||
"OrganizePatternResult": "Result: {0}",
|
"OrganizePatternResult": "Result: {0}",
|
||||||
"AutoOrganizeError": "Error Organizing File",
|
"AutoOrganizeError": "Error Organizing File",
|
||||||
|
"FileOrganizeManually": "Organize File",
|
||||||
"ErrorOrganizingFileWithErrorCode": "There was an error organizing the file. Error code: {0}.",
|
"ErrorOrganizingFileWithErrorCode": "There was an error organizing the file. Error code: {0}.",
|
||||||
"HeaderRestart": "Restart",
|
"HeaderRestart": "Restart",
|
||||||
"HeaderShutdown": "Shutdown",
|
"HeaderShutdown": "Shutdown",
|
||||||
|
|
|
@ -264,6 +264,7 @@
|
||||||
"HeaderSelectWatchFolderHelp": "Browse or enter the path to your watch folder. The folder must be writeable.",
|
"HeaderSelectWatchFolderHelp": "Browse or enter the path to your watch folder. The folder must be writeable.",
|
||||||
"OrganizePatternResult": "Result: {0}",
|
"OrganizePatternResult": "Result: {0}",
|
||||||
"AutoOrganizeError": "Error Organizing File",
|
"AutoOrganizeError": "Error Organizing File",
|
||||||
|
"FileOrganizeManually": "Organize File",
|
||||||
"ErrorOrganizingFileWithErrorCode": "There was an error organizing the file. Error code: {0}.",
|
"ErrorOrganizingFileWithErrorCode": "There was an error organizing the file. Error code: {0}.",
|
||||||
"HeaderRestart": "Restart",
|
"HeaderRestart": "Restart",
|
||||||
"HeaderShutdown": "Shutdown",
|
"HeaderShutdown": "Shutdown",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue