mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Move the conflicts filter UI into the Filters sidebar tab
Instead of having a toggle button in each card's dropdown menu, implement it as a dropdown menu in the Filters sidebar tab, containing a list of plugin filenames, plus a "No plugin" option. Closes #580.
This commit is contained in:
@@ -321,7 +321,7 @@ figure > div {
|
||||
<li>The <q>Empty Plugin</q> icon.
|
||||
<li>The <q>Loads Archive</q> icon.
|
||||
<li>The <q>Has User Metadata</q> icon.
|
||||
<li>The plugin menu button, which provides access to a few plugin-specific features, including a conflict filter and access to it in the metadata editor. These are explained in later sections.
|
||||
<li>The plugin menu button, which provides access to metadata-related features for the plugin. These are explained in later sections.
|
||||
</ol>
|
||||
|
||||
<p>Bash Tag suggestions and messages are displayed below the plugin card's header.
|
||||
@@ -342,13 +342,10 @@ figure > div {
|
||||
<li><i>Hide inactive plugins</i>: Hides all plugins that are inactive.
|
||||
<li><i>Hide messageless plugins</i>: Hides all plugins that have no visible messages.
|
||||
</ul>
|
||||
<p>The filter toggles have their states saved on quitting LOOT, and they are restored when LOOT is next launched. There are also two other filters:
|
||||
<p>The filter toggles have their states saved on quitting LOOT, and they are restored when LOOT is next launched. There are also two other filters in the sidebar tab:
|
||||
<ul>
|
||||
<li>A content filter, located beneath the filter toggles in the <span class="button">Filters</span> sidebar tab. This hides any plugins that don't have the filter input value present in any of the text on their cards.
|
||||
<li>A conflict filter that can be accessed through each plugin card's menu. This filters the plugin cards displayed so that only plugins which conflict with this plugin will be visible. If this plugin loads an archive, other plugins that load archives which <em>may</em> contain conflicting resources are also displayed.</p>
|
||||
|
||||
Only one plugin's conflict filter can be active at any one time, so activating a second conflict filter will deactivate the first. The plugin for which the filter is currently active has its card highlighted. Sorting with a conflict filter active will first deactivate it.
|
||||
|
||||
<li>A content filter. This hides any plugins that don't have the filter input value present in any of the text on their cards.
|
||||
<li>A conflict filter. This filters the plugin cards displayed so that only plugins which conflict with this plugin will be visible. If this plugin loads an archive, other plugins that load archives which <em>may</em> contain conflicting resources are also displayed. Sorting with the conflict filter active will first deactivate it.
|
||||
</ul>
|
||||
|
||||
<h3 id="usage-editing">Editing Plugin Metadata</h3>
|
||||
|
||||
@@ -78,6 +78,10 @@ div[drawer] > iron-pages {
|
||||
padding: 0 16px;
|
||||
height: 48px;
|
||||
}
|
||||
#conflictsFilter {
|
||||
padding: 0 16px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
/* Panel */
|
||||
#main {
|
||||
|
||||
@@ -1,16 +1,3 @@
|
||||
<!-- Fires the following events:
|
||||
|
||||
loot-editor-open
|
||||
|
||||
loot-filter-conflicts
|
||||
detail: boolean
|
||||
True if the filter has been activated.
|
||||
|
||||
loot-copy-metadata
|
||||
|
||||
loot-clear-metadata
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../../../bower_components/polymer/polymer.html">
|
||||
|
||||
<link rel="import" href="../../../../bower_components/iron-flex-layout/iron-flex-layout.html">
|
||||
@@ -104,13 +91,6 @@ loot-clear-metadata
|
||||
#clearMetadata {
|
||||
cursor: pointer;
|
||||
}
|
||||
#showOnlyConflicts {
|
||||
min-height: 48px;
|
||||
padding: 0 16px;
|
||||
font-weight: 500;
|
||||
--paper-toggle-button-label-spacing: 16px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
@@ -135,7 +115,6 @@ loot-clear-metadata
|
||||
<paper-menu-button id="menu" horizontal-align="right">
|
||||
<paper-icon-button icon="more-vert" class="dropdown-trigger"></paper-icon-button>
|
||||
<loot-menu class="dropdown-content">
|
||||
<paper-toggle-button id="showOnlyConflicts" checked="{{data.isConflictFilterChecked}}">Show Only Conflicts</paper-toggle-button>
|
||||
<paper-icon-item id="editMetadata">
|
||||
<iron-icon icon="create" item-icon></iron-icon>
|
||||
Edit Metadata
|
||||
@@ -177,14 +156,12 @@ loot-clear-metadata
|
||||
},
|
||||
|
||||
attached() {
|
||||
this.$.showOnlyConflicts.addEventListener('change', this._onShowOnlyConflicts);
|
||||
this.$.editMetadata.addEventListener('click', this.onShowEditor);
|
||||
this.$.copyMetadata.addEventListener('click', this._onCopyMetadata);
|
||||
this.$.clearMetadata.addEventListener('click', this._onClearMetadata);
|
||||
},
|
||||
|
||||
detached() {
|
||||
this.$.showOnlyConflicts.removeEventListener('change', this._onShowOnlyConflicts);
|
||||
this.$.editMetadata.removeEventListener('click', this.onShowEditor);
|
||||
this.$.copyMetadata.removeEventListener('click', this._onCopyMetadata);
|
||||
this.$.clearMetadata.removeEventListener('click', this._onClearMetadata);
|
||||
@@ -201,9 +178,6 @@ loot-clear-metadata
|
||||
this.$.isMaster.hidden = !this.data.isMaster;
|
||||
this.$.isEmpty.hidden = !this.data.isEmpty;
|
||||
this.$.loadsArchive.hidden = !this.data.loadsArchive;
|
||||
|
||||
/* Also set highlight if the conflict filter is active. */
|
||||
this.classList.toggle('highlight', this.data.isConflictFilterChecked);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -256,9 +230,6 @@ loot-clear-metadata
|
||||
this.dispatchEvent(new CustomEvent('iron-resize', { bubbles: true }));
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the conflict filter toggle state. */
|
||||
this.$.showOnlyConflicts.checked = this.data.isConflictFilterChecked;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -282,13 +253,6 @@ loot-clear-metadata
|
||||
}));
|
||||
},
|
||||
|
||||
_onShowOnlyConflicts(evt) {
|
||||
evt.target.dispatchEvent(new CustomEvent('loot-filter-conflicts', {
|
||||
detail: evt.currentTarget.checked,
|
||||
bubbles: true,
|
||||
}));
|
||||
},
|
||||
|
||||
_onCopyMetadata(evt) {
|
||||
evt.target.dispatchEvent(new CustomEvent('loot-copy-metadata', {
|
||||
bubbles: true,
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<link rel="import" href="../../../bower_components/neon-animation/animations/fade-out-animation.html">
|
||||
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../../bower_components/paper-item/paper-item-shared-styles.html">
|
||||
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-input/paper-input.html">
|
||||
@@ -45,6 +46,7 @@
|
||||
<link rel="import" href="../../../bower_components/paper-toggle-button/paper-toggle-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-toolbar/paper-toolbar.html">
|
||||
<link rel="import" href="../../../bower_components/paper-tooltip/paper-tooltip.html">
|
||||
|
||||
<style is="custom-style">
|
||||
div[drawer],
|
||||
div[main] {
|
||||
@@ -81,6 +83,11 @@
|
||||
@apply(--layout-horizontal);
|
||||
@apply(--layout-center);
|
||||
}
|
||||
#conflictsFilter {
|
||||
--paper-dropdown-menu: {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* Paper element styling.
|
||||
Colour variables are from Polymer's paper-styles element. */
|
||||
@@ -156,6 +163,14 @@
|
||||
</head>
|
||||
<!-- oncontextmenu attribute disables the right-click menu. -->
|
||||
<body oncontextmenu="return false" unresolved>
|
||||
<!-- This style element needs to be here so that it loads after the Vulcanized
|
||||
imports, which are placed in a div that is the first child of body. -->
|
||||
<style is="custom-style" include="paper-item-shared-styles">
|
||||
.paper-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
<paper-drawer-panel id="container" drawer-width="33%">
|
||||
<div drawer>
|
||||
<paper-toolbar>
|
||||
@@ -187,6 +202,10 @@
|
||||
<paper-checkbox id="hideMessagelessPlugins">Hide messageless plugins</paper-checkbox>
|
||||
<paper-input id="contentFilter" label="Filter content" no-label-float></paper-input>
|
||||
<paper-tooltip for="contentFilter" position="bottom">Press Enter or click outside the input to set the filter.</paper-tooltip>
|
||||
<loot-dropdown-menu id="conflictsFilter" label="Show only conflicting plugins for" vertical-align="bottom">
|
||||
<div class="paper-item" value="">No plugin</div>
|
||||
<!-- Generated <div> plugin elements go here. -->
|
||||
</loot-dropdown-menu>
|
||||
<div id="filtersSpacer"></div>
|
||||
<div class="divider"></div>
|
||||
<div id="hiddenPlugins">
|
||||
|
||||
+12
-23
@@ -34,6 +34,9 @@ function onChangeGame(evt) {
|
||||
const gameInfo = JSON.parse(result, loot.Plugin.fromJson);
|
||||
loot.game = new loot.Game(gameInfo, loot.l10n);
|
||||
|
||||
/* Re-initialise conflicts filter plugin list. */
|
||||
loot.Filters.fillConflictsFilterList(loot.game.plugins);
|
||||
|
||||
/* Now update virtual lists. */
|
||||
filterPluginData(loot.game.plugins, loot.filters);
|
||||
|
||||
@@ -69,7 +72,7 @@ function onUpdateMasterlist() {
|
||||
}).catch(loot.handlePromiseError);
|
||||
}
|
||||
function onSortPlugins() {
|
||||
if (undoConflictsFilter()) {
|
||||
if (loot.filters.deactivateConflictsFilter()) {
|
||||
/* Conflicts filter was undone, update the displayed cards. */
|
||||
filterPluginData(loot.game.plugins, loot.filters);
|
||||
}
|
||||
@@ -231,6 +234,9 @@ function onContentRefresh() {
|
||||
const game = JSON.parse(result, loot.Plugin.fromJson);
|
||||
loot.game = new loot.Game(game, loot.l10n);
|
||||
|
||||
/* Re-initialise conflicts filter plugin list. */
|
||||
loot.Filters.fillConflictsFilterList(loot.game.plugins);
|
||||
|
||||
/* Reapply filters. */
|
||||
filterPluginData(loot.game.plugins, loot.filters);
|
||||
|
||||
@@ -402,32 +408,15 @@ function onEditorClose(evt) {
|
||||
loot.state.exitEditingState();
|
||||
}).catch(loot.handlePromiseError);
|
||||
}
|
||||
function undoConflictsFilter() {
|
||||
const wasConflictsFilterEnabled = loot.filters.deactivateConflictsFilter();
|
||||
|
||||
/* Deactivate any existing plugin conflict filter. */
|
||||
loot.game.plugins.forEach((plugin) => {
|
||||
plugin.isConflictFilterChecked = false;
|
||||
});
|
||||
/* Un-highlight any existing filter plugin. */
|
||||
const cards = document.getElementById('main').getElementsByTagName('loot-plugin-card');
|
||||
for (let i = 0; i < cards.length; ++i) {
|
||||
cards[i].classList.toggle('highlight', false);
|
||||
}
|
||||
|
||||
return wasConflictsFilterEnabled;
|
||||
}
|
||||
function onConflictsFilter(evt) {
|
||||
/* Deactivate any existing plugin conflict filter. */
|
||||
undoConflictsFilter();
|
||||
/* evt.detail is true if the filter has been activated. */
|
||||
if (evt.detail) {
|
||||
evt.target.data.isConflictFilterChecked = true;
|
||||
evt.target.classList.toggle('highlight', true);
|
||||
|
||||
loot.filters.deactivateConflictsFilter();
|
||||
/* evt.currentTarget.value is the name of the target plugin, or an empty string
|
||||
if the filter has been deactivated. */
|
||||
if (evt.currentTarget.value) {
|
||||
/* Now get conflicts for the plugin. */
|
||||
loot.Dialog.showProgress(loot.l10n.translate('Identifying conflicting plugins...'));
|
||||
loot.filters.activateConflictsFilter(evt.target.getName()).then((plugins) => {
|
||||
loot.filters.activateConflictsFilter(evt.currentTarget.value).then((plugins) => {
|
||||
plugins.forEach((plugin) => {
|
||||
const gamePlugin = loot.game.plugins.find(item => item.name === plugin.name);
|
||||
if (gamePlugin) {
|
||||
|
||||
@@ -94,4 +94,23 @@
|
||||
return plugins;
|
||||
}).catch(handlePromiseError);
|
||||
}
|
||||
|
||||
static fillConflictsFilterList(plugins) {
|
||||
const list = document.getElementById('conflictsFilter');
|
||||
|
||||
/* Remove any existing plugin items. */
|
||||
while (list.children.length > 1) {
|
||||
list.removeChild(list.lastElementChild);
|
||||
}
|
||||
|
||||
plugins.forEach(plugin => {
|
||||
const item = document.createElement('div');
|
||||
|
||||
item.className = 'paper-item';
|
||||
item.setAttribute('value', plugin.name);
|
||||
item.textContent = plugin.name;
|
||||
|
||||
list.appendChild(item);
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -49,10 +49,8 @@
|
||||
document.getElementById('hideInactivePlugins').addEventListener('change', onSidebarFilterToggle);
|
||||
document.getElementById('hideAllPluginMessages').addEventListener('change', onSidebarFilterToggle);
|
||||
document.getElementById('hideMessagelessPlugins').addEventListener('change', onSidebarFilterToggle);
|
||||
document.body.addEventListener('loot-filter-conflicts', onConflictsFilter);
|
||||
|
||||
/* Set up event handlers for content filter. */
|
||||
document.getElementById('contentFilter').addEventListener('change', onSidebarFilterToggle);
|
||||
document.getElementById('conflictsFilter').addEventListener('iron-select', onConflictsFilter);
|
||||
|
||||
/* Set up handlers for buttons. */
|
||||
document.getElementById('redatePluginsButton').addEventListener('click', onRedatePlugins);
|
||||
@@ -231,6 +229,7 @@
|
||||
appData.game = new Game(game, appData.l10n);
|
||||
document.getElementById('cardsNav').items = appData.game.plugins;
|
||||
document.getElementById('pluginCardList').items = appData.game.plugins;
|
||||
appData.Filters.fillConflictsFilterList(appData.game.plugins);
|
||||
applyEnabledFilters(appData.filters, appData.settings, appData.game.plugins);
|
||||
Dialog.closeProgress();
|
||||
});
|
||||
|
||||
@@ -185,7 +185,6 @@
|
||||
/* UI state variables */
|
||||
this.id = this.name.replace(/\s+/g, '');
|
||||
this._isEditorOpen = false;
|
||||
this.isConflictFilterChecked = false;
|
||||
this._isSearchResult = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
pluginCard.querySelector('paper-tooltip[for=loadsArchive]').textContent = l10n.translate('Loads Archive');
|
||||
pluginCard.querySelector('paper-tooltip[for=hasUserEdits]').textContent = l10n.translate('Has User Metadata');
|
||||
|
||||
pluginCard.getElementById('showOnlyConflicts').textContent = l10n.translate('Show Only Conflicts');
|
||||
pluginCard.getElementById('editMetadata').lastChild.textContent = l10n.translate('Edit Metadata');
|
||||
pluginCard.getElementById('copyMetadata').lastChild.textContent = l10n.translate('Copy Metadata');
|
||||
pluginCard.getElementById('clearMetadata').lastChild.textContent = l10n.translate('Clear User Metadata');
|
||||
@@ -202,6 +201,8 @@
|
||||
document.getElementById('hideAllPluginMessages').textContent = l10n.translate('Hide all plugin messages');
|
||||
document.getElementById('hideInactivePlugins').textContent = l10n.translate('Hide inactive plugins');
|
||||
document.getElementById('hideMessagelessPlugins').textContent = l10n.translate('Hide messageless plugins');
|
||||
document.getElementById('conflictsFilter').label = l10n.translate('Show only conflicting plugins for');
|
||||
document.getElementById('conflictsFilter').firstElementChild.textContent = l10n.translate('No plugin');
|
||||
document.getElementById('hiddenPluginsTxt').textContent = l10n.translate('Hidden plugins:');
|
||||
document.getElementById('hiddenMessagesTxt').textContent = l10n.translate('Hidden messages:');
|
||||
}
|
||||
|
||||
@@ -45,9 +45,6 @@
|
||||
function onEditorClose() {
|
||||
alert('Editor closed');
|
||||
}
|
||||
function onFilterConflicts() {
|
||||
alert('Conflicts filter toggle clicked');
|
||||
}
|
||||
function onCopyMetadata() {
|
||||
alert('Copy metadata button clicked');
|
||||
}
|
||||
@@ -77,7 +74,6 @@
|
||||
|
||||
document.addEventListener('loot-editor-open', onEditorOpen);
|
||||
document.addEventListener('loot-editor-close', onEditorClose);
|
||||
document.addEventListener('loot-filter-conflicts', onFilterConflicts);
|
||||
document.addEventListener('loot-copy-metadata', onCopyMetadata);
|
||||
document.addEventListener('loot-clear-metadata', onClearMetadata);
|
||||
|
||||
|
||||
@@ -408,7 +408,6 @@ describe('Game', () => {
|
||||
|
||||
id: '',
|
||||
_isEditorOpen: true,
|
||||
isConflictFilterChecked: true,
|
||||
_isSearchResult: true,
|
||||
}];
|
||||
|
||||
|
||||
@@ -262,12 +262,6 @@ describe('Plugin', () => {
|
||||
plugin.isEditorOpen.should.be.false();
|
||||
});
|
||||
|
||||
it('should set isConflictFilterChecked to false', () => {
|
||||
const plugin = new loot.Plugin({ name: 'test' });
|
||||
|
||||
plugin.isConflictFilterChecked.should.be.false();
|
||||
});
|
||||
|
||||
it('should set isSearchResult to false', () => {
|
||||
const plugin = new loot.Plugin({ name: 'test' });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user