mirror of
https://github.com/krateng/maloja.git
synced 2025-04-15 16:30:32 +03:00
Reworked web UI editing
This commit is contained in:
parent
25ba050d30
commit
d8420cdb67
@ -23,6 +23,7 @@
|
||||
<script src="/neopolitan.js"></script>
|
||||
<script src="/upload.js"></script>
|
||||
<script src="/notifications.js"></script>
|
||||
<script src="/edit.js"></script>
|
||||
<script>
|
||||
const defaultpicks = {
|
||||
topartists: '{{ settings["DEFAULT_RANGE_STARTPAGE"] }}',
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/statselect.js"></script>
|
||||
<script src="/edit.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% set album = filterkeys.album %}
|
||||
@ -20,13 +19,21 @@
|
||||
{% block icon_bar %}
|
||||
{% if adminmode %}
|
||||
{% include 'icons/edit.jinja' %}
|
||||
|
||||
<div class="iconsubset mergeicons" data-entity_type="album" data-entity_id="{{ info.id }}" data-entity_name="{{ info.album.albumtitle }}">
|
||||
{% include 'icons/merge.jinja' %}
|
||||
{% include 'icons/merge_mark.jinja' %}
|
||||
{% include 'icons/merge_unmark.jinja' %}
|
||||
{% include 'icons/merge_cancel.jinja' %}
|
||||
</div>
|
||||
|
||||
<div class="iconsubset associateicons" data-entity_type="album" data-entity_id="{{ info.id }}" data-entity_name="{{ info.album.albumtitle }}">
|
||||
{% include 'icons/add_album.jinja' %}
|
||||
{% include 'icons/association_mark.jinja' %}
|
||||
{% include 'icons/association_unmark.jinja' %}
|
||||
{% include 'icons/association_cancel.jinja' %}
|
||||
<script>showValidMergeIcons();</script>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/statselect.js"></script>
|
||||
<script src="/edit.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% set artist = filterkeys.artist %}
|
||||
@ -30,11 +29,19 @@
|
||||
{% block icon_bar %}
|
||||
{% if adminmode %}
|
||||
{% include 'icons/edit.jinja' %}
|
||||
|
||||
<div class="iconsubset mergeicons" data-entity_type="artist" data-entity_id="{{ info.id }}" data-entity_name="{{ info.artist }}">
|
||||
{% include 'icons/merge.jinja' %}
|
||||
{% include 'icons/merge_mark.jinja' %}
|
||||
{% include 'icons/merge_unmark.jinja' %}
|
||||
{% include 'icons/merge_cancel.jinja' %}
|
||||
</div>
|
||||
|
||||
<div class="iconsubset associateicons" data-entity_type="artist" data-entity_id="{{ info.id }}" data-entity_name="{{ info.artist }}">
|
||||
{% include 'icons/add_artist.jinja' %}
|
||||
<script>showValidMergeIcons();</script>
|
||||
{% include 'icons/association_cancel.jinja' %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div title="Add to Album" id="associatealbumicon" class="clickable_icon" onclick="associate()">
|
||||
<div title="Add to Album" id="associatealbumicon" class="clickable_icon" onclick="associate(this)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
<path d="M2 4.75C2 3.784 2.784 3 3.75 3h4.971a1.75 1.75 0 0 1 1.447.765l1.404 2.063a.25.25 0 0 0 .207.11h8.471c.966 0 1.75.783 1.75 1.75V19.25A1.75 1.75 0 0 1 20.25 21H4.75a.75.75 0 0 1 0-1.5h15.5a.25.25 0 0 0 .25-.25V7.688a.25.25 0 0 0-.25-.25h-8.471a1.751 1.751 0 0 1-1.447-.766L8.928 4.609a.252.252 0 0 0-.207-.109H3.75a.25.25 0 0 0-.25.25v3.5a.75.75 0 0 1-1.5 0v-3.5Z"></path>
|
||||
<path d="m9.308 12.5-2.104-2.236a.75.75 0 1 1 1.092-1.028l3.294 3.5a.75.75 0 0 1 0 1.028l-3.294 3.5a.75.75 0 1 1-1.092-1.028L9.308 14H4.09a2.59 2.59 0 0 0-2.59 2.59v3.16a.75.75 0 0 1-1.5 0v-3.16a4.09 4.09 0 0 1 4.09-4.09h5.218Z"></path>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div title="Add Artist" id="associateartisticon" class="clickable_icon" onclick="associate()">
|
||||
<div title="Add Artist" id="associateartisticon" class="clickable_icon" onclick="associate(this)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
<path d="M4 9.5a5 5 0 1 1 7.916 4.062 7.973 7.973 0 0 1 5.018 7.166.75.75 0 1 1-1.499.044 6.469 6.469 0 0 0-12.932 0 .75.75 0 0 1-1.499-.044 7.972 7.972 0 0 1 5.059-7.181A4.994 4.994 0 0 1 4 9.5ZM9 6a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7Zm10.25-5a.75.75 0 0 1 .75.75V4h2.25a.75.75 0 0 1 0 1.5H20v2.25a.75.75 0 0 1-1.5 0V5.5h-2.25a.75.75 0 0 1 0-1.5h2.25V1.75a.75.75 0 0 1 .75-.75Z"></path>
|
||||
</svg>
|
||||
|
@ -1,7 +1,6 @@
|
||||
<div title="Cancel Track Association" id="associationcancelicon" class="clickable_icon" onclick="umarkForAssociate(this)">
|
||||
<div title="Cancel associating" class="associatecancelicon clickable_icon" onclick="cancelAssociate(this)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M2.345 20.595 8.47 14.47q.219-.22.53-.22.311 0 .53.22.22.219.22.53 0 .311-.22.53l-6.125 6.125q-.219.22-.53.22-.311 0-.53-.22-.22-.219-.22-.53 0-.311.22-.53Z"></path>
|
||||
<path d="m16.72 11.97.358-.358a6.738 6.738 0 0 1 2.326-1.518l1.896-.738a.25.25 0 0 0 .086-.409l-6.333-6.333a.25.25 0 0 0-.409.086l-.521 1.34a8.663 8.663 0 0 1-2.243 3.265.75.75 0 0 1-1.01-1.11 7.132 7.132 0 0 0 1.854-2.699l.521-1.34a1.75 1.75 0 0 1 2.869-.603l6.333 6.333a1.75 1.75 0 0 1-.603 2.869l-1.896.737a5.26 5.26 0 0 0-1.81 1.18l-.358.358a.749.749 0 1 1-1.06-1.06Zm-12.549-.738a1.75 1.75 0 0 1 .757-2.92l3.366-.962.412 1.443-3.366.961a.25.25 0 0 0-.108.417l8.597 8.597a.25.25 0 0 0 .417-.108l.961-3.366 1.443.412-.962 3.366a1.75 1.75 0 0 1-2.92.757Z"></path>
|
||||
<path d="m3.405 2.095 18.75 18.75q.22.219.22.53 0 .311-.22.53-.219.22-.53.22-.311 0-.53-.22L2.345 3.155q-.22-.219-.22-.53 0-.311.22-.53.219-.22.53-.22.311 0 .53.22Z"></path>
|
||||
<path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM5.834 19.227A9.464 9.464 0 0 0 12 21.5a9.5 9.5 0 0 0 9.5-9.5 9.464 9.464 0 0 0-2.273-6.166ZM2.5 12a9.464 9.464 0 0 0 2.273 6.166L18.166 4.773A9.463 9.463 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Z">
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div title="Mark to associate artists or album" id="associationmarkicon" class="clickable_icon" onclick="markForAssociate(this)">
|
||||
<div title="Mark for association" class="associationmarkicon clickable_icon" onclick="markForAssociate(this)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="m16.114 1.553 6.333 6.333a1.75 1.75 0 0 1-.603 2.869l-1.63.633a5.67 5.67 0 0 0-3.395 3.725l-1.131 3.959a1.75 1.75 0 0 1-2.92.757L9 16.061l-5.595 5.594a.749.749 0 1 1-1.06-1.06L7.939 15l-3.768-3.768a1.75 1.75 0 0 1 .757-2.92l3.959-1.131a5.666 5.666 0 0 0 3.725-3.395l.633-1.63a1.75 1.75 0 0 1 2.869-.603ZM5.232 10.171l8.597 8.597a.25.25 0 0 0 .417-.108l1.131-3.959A7.17 7.17 0 0 1 19.67 9.99l1.63-.634a.25.25 0 0 0 .086-.409l-6.333-6.333a.25.25 0 0 0-.409.086l-.634 1.63a7.17 7.17 0 0 1-4.711 4.293L5.34 9.754a.25.25 0 0 0-.108.417Z"></path>
|
||||
</svg>
|
||||
|
7
maloja/web/jinja/icons/association_unmark.jinja
Normal file
7
maloja/web/jinja/icons/association_unmark.jinja
Normal file
@ -0,0 +1,7 @@
|
||||
<div title="Unmark for Association"class="associationunmarkicon clickable_icon" onclick="umarkForAssociate(this)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M2.345 20.595 8.47 14.47q.219-.22.53-.22.311 0 .53.22.22.219.22.53 0 .311-.22.53l-6.125 6.125q-.219.22-.53.22-.311 0-.53-.22-.22-.219-.22-.53 0-.311.22-.53Z"></path>
|
||||
<path d="m16.72 11.97.358-.358a6.738 6.738 0 0 1 2.326-1.518l1.896-.738a.25.25 0 0 0 .086-.409l-6.333-6.333a.25.25 0 0 0-.409.086l-.521 1.34a8.663 8.663 0 0 1-2.243 3.265.75.75 0 0 1-1.01-1.11 7.132 7.132 0 0 0 1.854-2.699l.521-1.34a1.75 1.75 0 0 1 2.869-.603l6.333 6.333a1.75 1.75 0 0 1-.603 2.869l-1.896.737a5.26 5.26 0 0 0-1.81 1.18l-.358.358a.749.749 0 1 1-1.06-1.06Zm-12.549-.738a1.75 1.75 0 0 1 .757-2.92l3.366-.962.412 1.443-3.366.961a.25.25 0 0 0-.108.417l8.597 8.597a.25.25 0 0 0 .417-.108l.961-3.366 1.443.412-.962 3.366a1.75 1.75 0 0 1-2.92.757Z"></path>
|
||||
<path d="m3.405 2.095 18.75 18.75q.22.219.22.53 0 .311-.22.53-.219.22-.53.22-.311 0-.53-.22L2.345 3.155q-.22-.219-.22-.53 0-.311.22-.53.219-.22.53-.22.311 0 .53.22Z"></path>
|
||||
</svg>
|
||||
</div>
|
@ -1,4 +1,4 @@
|
||||
<div title="Merge" id="mergeicon" class="clickable_icon hide" onclick="merge()">
|
||||
<div title="Merge" id="mergeicon" class="clickable_icon" onclick="merge(this)">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24">
|
||||
<path fill-rule="evenodd" d="M5 3.254V3.25v.005a.75.75 0 110-.005v.004zm.45 1.9a2.25 2.25 0 10-1.95.218v5.256a2.25 2.25 0 101.5 0V7.123A5.735 5.735 0 009.25 9h1.378a2.251 2.251 0 100-1.5H9.25a4.25 4.25 0 01-3.8-2.346zM12.75 9a.75.75 0 100-1.5.75.75 0 000 1.5zm-8.5 4.5a.75.75 0 100-1.5.75.75 0 000 1.5z"></path>
|
||||
</svg>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<div title="Cancel merge" id="mergecancelicon" class="clickable_icon hide" onclick="cancelMerge()">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24">
|
||||
<path fill-rule="evenodd" d="M10.72 1.227a.75.75 0 011.06 0l.97.97.97-.97a.75.75 0 111.06 1.061l-.97.97.97.97a.75.75 0 01-1.06 1.06l-.97-.97-.97.97a.75.75 0 11-1.06-1.06l.97-.97-.97-.97a.75.75 0 010-1.06zM12.75 6.5a.75.75 0 00-.75.75v3.378a2.251 2.251 0 101.5 0V7.25a.75.75 0 00-.75-.75zm0 5.5a.75.75 0 100 1.5.75.75 0 000-1.5zM2.5 3.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.25 1a2.25 2.25 0 00-.75 4.372v5.256a2.251 2.251 0 101.5 0V5.372A2.25 2.25 0 003.25 1zm0 11a.75.75 0 100 1.5.75.75 0 000-1.5z"></path>
|
||||
<div title="Cancel merging" id="mergecancelicon" class="clickable_icon" onclick="cancelMerge(this)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM5.834 19.227A9.464 9.464 0 0 0 12 21.5a9.5 9.5 0 0 0 9.5-9.5 9.464 9.464 0 0 0-2.273-6.166ZM2.5 12a9.464 9.464 0 0 0 2.273 6.166L18.166 4.773A9.463 9.463 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Z">
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div title="Mark for merging" id="mergemarkicon" class="clickable_icon hide" onclick="markForMerge()">
|
||||
<div title="Mark for merging" id="mergemarkicon" class="clickable_icon" onclick="markForMerge(this)">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24">
|
||||
<path fill-rule="evenodd" d="M7.177 3.073L9.573.677A.25.25 0 0110 .854v4.792a.25.25 0 01-.427.177L7.177 3.427a.25.25 0 010-.354zM3.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122v5.256a2.251 2.251 0 11-1.5 0V5.372A2.25 2.25 0 011.5 3.25zM11 2.5h-1V4h1a1 1 0 011 1v5.628a2.251 2.251 0 101.5 0V5A2.5 2.5 0 0011 2.5zm1 10.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.75 12a.75.75 0 100 1.5.75.75 0 000-1.5z"></path>
|
||||
</svg>
|
||||
|
5
maloja/web/jinja/icons/merge_unmark.jinja
Normal file
5
maloja/web/jinja/icons/merge_unmark.jinja
Normal file
@ -0,0 +1,5 @@
|
||||
<div title="Unmark from merge" id="mergeunmarkicon" class="clickable_icon" onclick="unmarkForMerge(this)">
|
||||
<svg viewBox="0 0 16 16" width="24" height="24">
|
||||
<path fill-rule="evenodd" d="M10.72 1.227a.75.75 0 011.06 0l.97.97.97-.97a.75.75 0 111.06 1.061l-.97.97.97.97a.75.75 0 01-1.06 1.06l-.97-.97-.97.97a.75.75 0 11-1.06-1.06l.97-.97-.97-.97a.75.75 0 010-1.06zM12.75 6.5a.75.75 0 00-.75.75v3.378a2.251 2.251 0 101.5 0V7.25a.75.75 0 00-.75-.75zm0 5.5a.75.75 0 100 1.5.75.75 0 000-1.5zM2.5 3.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.25 1a2.25 2.25 0 00-.75 4.372v5.256a2.251 2.251 0 101.5 0V5.372A2.25 2.25 0 003.25 1zm0 11a.75.75 0 100 1.5.75.75 0 000-1.5z"></path>
|
||||
</svg>
|
||||
</div>
|
@ -28,11 +28,12 @@
|
||||
{% set firstindex = amountkeys.page * amountkeys.perpage %}
|
||||
{% set lastindex = firstindex + amountkeys.perpage %}
|
||||
|
||||
|
||||
{% set maxbar = charts[0]['scrobbles'] if charts != [] else 0 %}
|
||||
<table class='list'>
|
||||
{% for e in charts %}
|
||||
{% if loop.index0 >= firstindex and loop.index0 < lastindex %}
|
||||
<tr>
|
||||
<tr class="listrow associateicons" data-entity_id="{{ e['album_id'] }}" data-entity_type="album" data-entity_name="{{ e['album'].albumtitle }}">
|
||||
<!-- Rank -->
|
||||
<td class="rank">{%if loop.changed(e.scrobbles) %}#{{ e.rank }}{% endif %}</td>
|
||||
<!-- Rank change -->
|
||||
@ -45,7 +46,7 @@
|
||||
{% endif %}
|
||||
|
||||
<!-- artist -->
|
||||
{{ entityrow.row(e['album']) }}
|
||||
{{ entityrow.row(e['album'],adminmode=True) }}
|
||||
|
||||
<!-- scrobbles -->
|
||||
<td class="amount">{{ links.link_scrobbles([{'album':e.album,'timerange':limitkeys.timerange}],amount=e['scrobbles']) }}</td>
|
||||
|
@ -30,12 +30,13 @@
|
||||
{% set lastindex = firstindex + amountkeys.perpage %}
|
||||
|
||||
|
||||
|
||||
{% set maxbar = charts[0]['scrobbles'] if charts != [] else 0 %}
|
||||
|
||||
<table class='list'>
|
||||
{% for e in charts %}
|
||||
{% if loop.index0 >= firstindex and loop.index0 < lastindex %}
|
||||
<tr>
|
||||
<tr class="listrow associateicons" data-entity_id="{{ e['artist_id'] }}" data-entity_type="artist" data-entity_name="{{ e['artist'] }}">
|
||||
<!-- Rank -->
|
||||
<td class="rank">{%if loop.changed(e.scrobbles) %}#{{ e.rank }}{% endif %}</td>
|
||||
<!-- Rank change -->
|
||||
@ -48,7 +49,7 @@
|
||||
{% endif %}
|
||||
|
||||
<!-- artist -->
|
||||
{{ entityrow.row(e['artist']) }}
|
||||
{{ entityrow.row(e['artist'],adminmode=True) }}
|
||||
|
||||
<!-- scrobbles -->
|
||||
<td class="amount">{{ links.link_scrobbles([{'artist':e['artist'],'associated':True,'timerange':limitkeys.timerange}],amount=e['scrobbles']) }}</td>
|
||||
|
@ -28,11 +28,12 @@
|
||||
{% set firstindex = amountkeys.page * amountkeys.perpage %}
|
||||
{% set lastindex = firstindex + amountkeys.perpage %}
|
||||
|
||||
|
||||
{% set maxbar = charts[0]['scrobbles'] if charts != [] else 0 %}
|
||||
<table class='list'>
|
||||
{% for e in charts %}
|
||||
{% if loop.index0 >= firstindex and loop.index0 < lastindex %}
|
||||
<tr>
|
||||
<tr class="listrow associateicons" data-entity_id="{{ e['track_id'] }}" data-entity_type="track" data-entity_name="{{ e['track'].title }}">
|
||||
<!-- Rank -->
|
||||
<td class="rank">{%if loop.changed(e.scrobbles) %}#{{ e.rank }}{% endif %}</td>
|
||||
<!-- Rank change -->
|
||||
@ -45,7 +46,7 @@
|
||||
{% endif %}
|
||||
|
||||
<!-- artist -->
|
||||
{{ entityrow.row(e['track']) }}
|
||||
{{ entityrow.row(e['track'],adminmode=True) }}
|
||||
|
||||
<!-- scrobbles -->
|
||||
<td class="amount">{{ links.link_scrobbles([{'track':e.track,'timerange':limitkeys.timerange}],amount=e['scrobbles']) }}</td>
|
||||
|
@ -6,22 +6,14 @@
|
||||
{% set firstindex = amountkeys.page * amountkeys.perpage %}
|
||||
{% set lastindex = firstindex + amountkeys.perpage %}
|
||||
|
||||
<script src="/edit.js"></script>
|
||||
|
||||
<table class='list'>
|
||||
{% for e in list %}
|
||||
{% if loop.index0 >= firstindex and loop.index0 < lastindex %}
|
||||
<tr class="listrow unmarked" data-entity_id="{{ e['track_id'] }}" data-entity_type="track" data-entity_name="{{ e['track'].title }}">
|
||||
<tr class="listrow associateicons" data-entity_id="{{ e['track_id'] }}" data-entity_type="track" data-entity_name="{{ e['track'].title }}">
|
||||
|
||||
<!-- artist -->
|
||||
{{ entityrow.row(e['track']) }}
|
||||
|
||||
{% with inlineicons = True %}
|
||||
<td>
|
||||
{% include 'icons/association_mark.jinja' %}
|
||||
{% include 'icons/association_cancel.jinja' %}
|
||||
</td>
|
||||
{% endwith %}
|
||||
{{ entityrow.row(e['track'],adminmode=adminmode) }}
|
||||
|
||||
</tr>
|
||||
{% endif %}
|
||||
@ -30,9 +22,6 @@
|
||||
|
||||
<script>
|
||||
|
||||
var listrows = document.getElementsByClassName('listrow');
|
||||
for (var row of listrows) {
|
||||
toggleAssociationIcons(row);
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
@ -6,9 +6,6 @@
|
||||
{% import 'snippets/entityrow.jinja' as entityrow %}
|
||||
|
||||
|
||||
<script src="/edit.js"></script>
|
||||
|
||||
|
||||
<table class='list'>
|
||||
{% for s in scrobbles -%}
|
||||
{%- if loop.index0 >= firstindex and loop.index0 < lastindex -%}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% macro row(entity,counting=[]) %}
|
||||
{% macro row(entity,counting=[],adminmode=False) %}
|
||||
|
||||
{% import 'snippets/links.jinja' as links %}
|
||||
|
||||
@ -35,4 +35,11 @@
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if adminmode and (entity is mapping) %}
|
||||
<td>
|
||||
{% include 'icons/association_mark.jinja' %}
|
||||
{% include 'icons/association_unmark.jinja' %}
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
{% endmacro %}
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/statselect.js"></script>
|
||||
<script src="/edit.js"></script>
|
||||
<script>
|
||||
function scrobble(encodedtrack) {
|
||||
neo.xhttprequest('/apis/mlj_1/newscrobble?nofix&' + encodedtrack,data={},method="POST").then(response=>{window.location.reload()});
|
||||
@ -25,12 +24,19 @@
|
||||
{% block icon_bar %}
|
||||
{% if adminmode %}
|
||||
{% include 'icons/edit.jinja' %}
|
||||
|
||||
<div class="iconsubset mergeicons" data-entity_type="track" data-entity_id="{{ info.id }}" data-entity_name="{{ info.track.title }}">
|
||||
{% include 'icons/merge.jinja' %}
|
||||
{% include 'icons/merge_mark.jinja' %}
|
||||
{% include 'icons/merge_unmark.jinja' %}
|
||||
{% include 'icons/merge_cancel.jinja' %}
|
||||
</div>
|
||||
|
||||
<div class="iconsubset associateicons" data-entity_type="track" data-entity_id="{{ info.id }}" data-entity_name="{{ info.track.title }}">
|
||||
{% include 'icons/association_mark.jinja' %}
|
||||
{% include 'icons/association_unmark.jinja' %}
|
||||
{% include 'icons/association_cancel.jinja' %}
|
||||
<script>showValidMergeIcons();</script>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -67,6 +67,10 @@ div#icon_bar {
|
||||
right:30px;
|
||||
top:30px;
|
||||
}
|
||||
.iconsubset {
|
||||
display: inline-block;
|
||||
padding-left:20px;
|
||||
}
|
||||
|
||||
div#icon_bar div.clickable_icon {
|
||||
display: inline-block;
|
||||
@ -94,14 +98,75 @@ div.clickable_icon.danger:hover svg {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.list tr.marked {
|
||||
background-color: rgba(50,20,0,0.5);
|
||||
.list {
|
||||
--color_bg_merge: rgba(0,0,90,0.7);
|
||||
--color_fg_merge: lightblue;
|
||||
--color_bg_associate: rgba(50,20,0,0.7);
|
||||
--color_fg_associate: orange;
|
||||
}
|
||||
.list tr.marked #associationmarkicon {
|
||||
display:none;
|
||||
|
||||
.list tr.marked_for_associate {
|
||||
background-color: var(--color_bg_associate);
|
||||
color: var(--color_fg_associate);
|
||||
}
|
||||
.list tr:not(.marked) #associationcancelicon {
|
||||
display:none;
|
||||
.list tr.marked_for_merge {
|
||||
background-color: var(--color_bg_merge);
|
||||
color: var(--color_fg_merge);;
|
||||
}
|
||||
|
||||
@keyframes slideBackground {
|
||||
0% {
|
||||
background-position: 100% 0;
|
||||
}
|
||||
50% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
100% {
|
||||
background-position: 100% 0;
|
||||
}
|
||||
}
|
||||
@keyframes colorChange {
|
||||
0% {
|
||||
color: var(--color_fg_associate);
|
||||
}
|
||||
50% {
|
||||
color: var(--color_fg_merge);
|
||||
}
|
||||
100% {
|
||||
color: var(--color_fg_associate);
|
||||
}
|
||||
}
|
||||
|
||||
.list tr.marked_for_associate.marked_for_merge {
|
||||
background: linear-gradient(to left, var(--color_bg_associate), var(--color_bg_merge));
|
||||
background-size: 100% 100%;
|
||||
animation: colorChange 4s infinite ease-in-out;
|
||||
}
|
||||
|
||||
|
||||
/* this is just to 'factor out' that big selector down there.
|
||||
we want icons to not be displayed in list rows, but show them with reduced opacity in the top bar */
|
||||
.list {
|
||||
--display_inactive_icons: none;
|
||||
}
|
||||
#icon_bar {
|
||||
--display_inactive_icons: inline-block;
|
||||
}
|
||||
|
||||
.associateicons.marked_for_associate .associationmarkicon, /* already marked, cant mark again */
|
||||
.associateicons:not(.marked_for_associate) .associationunmarkicon, /* not marked, cant unmark */
|
||||
.associateicons:not(.somethingmarked_for_associate) .associatecancelicon, /* cant cancel when nothing is marked */
|
||||
.mergeicons.marked_for_merge #mergemarkicon, /* already marked, cant mark again */
|
||||
.mergeicons:not(.marked_for_merge) #mergeunmarkicon, /* not marked, cant unmark */
|
||||
.mergeicons:not(.somethingmarked_for_merge) #mergecancelicon, /* cant cancel when nothing is marked */
|
||||
.mergeicons:not(.somethingmarked_for_merge) #mergeicon, /* can't merge when nothing is selected */
|
||||
.mergeicons.marked_for_merge #mergeicon, /* cant merge into one of the things we have selected */
|
||||
.associateicons:not(.sources_marked_for_associate) #associatealbumicon,
|
||||
.associateicons:not(.sources_marked_for_associate) #associateartisticon /* nothing marked yet, can't associate with this */
|
||||
{
|
||||
pointer-events: none;
|
||||
opacity:0.5;
|
||||
display: var(--display_inactive_icons);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -187,186 +187,117 @@ function doneEditing() {
|
||||
}
|
||||
}
|
||||
|
||||
// MERGING
|
||||
// MERGING AND ASSOCIATION
|
||||
|
||||
function showValidMergeIcons() {
|
||||
const associate_targets = {
|
||||
album: ['artist'],
|
||||
track: ['album','artist'],
|
||||
artist: []
|
||||
};
|
||||
|
||||
// merge
|
||||
const associate_sources = {
|
||||
artist: ['album','track'],
|
||||
album: ['track'],
|
||||
track: []
|
||||
};
|
||||
|
||||
|
||||
function getStoredList(key) {
|
||||
const lcst = window.sessionStorage;
|
||||
var key = "marked_for_merge_" + entity_type;
|
||||
var current_stored = (lcst.getItem(key) || '').split(",");
|
||||
current_stored = current_stored.filter((x)=>x).map((x)=>parseInt(x));
|
||||
|
||||
var mergeicon = document.getElementById('mergeicon');
|
||||
var mergemarkicon = document.getElementById('mergemarkicon');
|
||||
var mergecancelicon = document.getElementById('mergecancelicon');
|
||||
|
||||
mergeicon.classList.add('hide');
|
||||
mergemarkicon.classList.add('hide');
|
||||
mergecancelicon.classList.add('hide');
|
||||
|
||||
if (current_stored.length == 0) {
|
||||
mergemarkicon.classList.remove('hide');
|
||||
}
|
||||
else {
|
||||
mergecancelicon.classList.remove('hide');
|
||||
|
||||
if (current_stored.includes(entity_id)) {
|
||||
|
||||
}
|
||||
else {
|
||||
mergemarkicon.classList.remove('hide');
|
||||
mergeicon.classList.remove('hide');
|
||||
}
|
||||
}
|
||||
|
||||
// mark for association
|
||||
if ((entity_type == 'track') || (entity_type == 'album')) {
|
||||
const lcst = window.sessionStorage;
|
||||
var key = "marked_for_associate_" + entity_type;
|
||||
var current_stored = (lcst.getItem(key) || '').split(",");
|
||||
current_stored = current_stored.filter((x)=>x).map((x)=>parseInt(x));
|
||||
|
||||
var associationmarkicon = document.getElementById('associationmarkicon');
|
||||
var associationcancelicon = document.getElementById('associationcancelicon');
|
||||
|
||||
associationmarkicon.classList.add('hide');
|
||||
associationcancelicon.classList.add('hide');
|
||||
|
||||
|
||||
if (current_stored.length == 0) {
|
||||
associationmarkicon.classList.remove('hide');
|
||||
}
|
||||
else {
|
||||
associationcancelicon.classList.remove('hide');
|
||||
|
||||
if (current_stored.includes(entity_id)) {
|
||||
|
||||
}
|
||||
else {
|
||||
associationmarkicon.classList.remove('hide');
|
||||
}
|
||||
}
|
||||
|
||||
if (entity_type == 'track') {
|
||||
associationmarkicon.title = "Mark this track to add to album or add artist";
|
||||
}
|
||||
else {
|
||||
associationmarkicon.title = "Mark this album to add artist";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// association confirm
|
||||
if ((entity_type == 'artist') || (entity_type == 'album')) {
|
||||
var target_entity_types = {artist:['album','track'], album:['track']};
|
||||
var to_associate = {};
|
||||
var to_associate_all = [];
|
||||
for (var target_entity_type of target_entity_types[entity_type]) {
|
||||
const lcst = window.sessionStorage;
|
||||
var key = "marked_for_associate_" + target_entity_type;
|
||||
var current_stored = (lcst.getItem(key) || '').split(",");
|
||||
to_associate[target_entity_type] = current_stored.filter((x)=>x).map((x)=>parseInt(x));
|
||||
to_associate_all = to_associate_all.concat(to_associate[target_entity_type]);
|
||||
}
|
||||
|
||||
var associateicon = document.getElementById('associate' + entity_type + 'icon');
|
||||
|
||||
associateicon.classList.add('hide');
|
||||
|
||||
|
||||
if (to_associate_all.length == 0) {
|
||||
|
||||
}
|
||||
else {
|
||||
associateicon.classList.remove('hide');
|
||||
if (entity_type == 'artist') {
|
||||
associateicon.title = "Add this artist to " + to_associate['album'].length + " albums and " + to_associate['track'].length + " tracks";
|
||||
}
|
||||
else {
|
||||
associateicon.title = "Add " + to_associate['track'].length + " tracks to this album";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return current_stored;
|
||||
}
|
||||
function storeList(key,list) {
|
||||
const lcst = window.sessionStorage;
|
||||
list = [...new Set(list)];
|
||||
lcst.setItem(key,list); //this already formats it correctly
|
||||
}
|
||||
|
||||
|
||||
function markForMerge() {
|
||||
const lcst = window.sessionStorage;
|
||||
var key = "marked_for_merge_" + entity_type;
|
||||
var current_stored = (lcst.getItem(key) || '').split(",");
|
||||
current_stored = current_stored.filter((x)=>x).map((x)=>parseInt(x));
|
||||
|
||||
function markForMerge(element) {
|
||||
const parentElement = element.closest('[data-entity_id]');
|
||||
|
||||
var entity_type = parentElement.dataset.entity_type;
|
||||
var entity_id = parentElement.dataset.entity_id;
|
||||
var entity_name = parentElement.dataset.entity_name;
|
||||
entity_id = parseInt(entity_id);
|
||||
|
||||
key = "marked_for_merge_" + entity_type;
|
||||
var current_stored = getStoredList(key);
|
||||
current_stored.push(entity_id);
|
||||
current_stored = [...new Set(current_stored)];
|
||||
lcst.setItem(key,current_stored); //this already formats it correctly
|
||||
storeList(key,current_stored)
|
||||
|
||||
notify("Marked " + entity_name + " for merge","Currently " + current_stored.length + " marked!")
|
||||
showValidMergeIcons();
|
||||
|
||||
toggleMergeIcons(parentElement);
|
||||
}
|
||||
|
||||
function unmarkForMerge(element) {
|
||||
const parentElement = element.closest('[data-entity_id]');
|
||||
|
||||
var entity_type = parentElement.dataset.entity_type;
|
||||
var entity_id = parentElement.dataset.entity_id;
|
||||
var entity_name = parentElement.dataset.entity_name;
|
||||
entity_id = parseInt(entity_id);
|
||||
|
||||
var key = "marked_for_merge_" + entity_type;
|
||||
var current_stored = getStoredList(key);
|
||||
|
||||
if (current_stored.indexOf(entity_id) > -1) {
|
||||
current_stored.splice(current_stored.indexOf(entity_id),1);
|
||||
storeList(key,current_stored);
|
||||
notify("Unmarked " + entity_name + " from merge","Currently " + current_stored.length + " marked!")
|
||||
|
||||
toggleMergeIcons(parentElement);
|
||||
}
|
||||
else {
|
||||
//notify(entity_name + " was not marked!","")
|
||||
}
|
||||
}
|
||||
|
||||
function markForAssociate(element) {
|
||||
console.log(element);
|
||||
const parentElement = element.closest('[data-entity_id]');
|
||||
console.log(parentElement);
|
||||
// use local element for entity data, otherwise use from global scope (on entity info page)
|
||||
var l_entity_type = parentElement ? parentElement.dataset.entity_type : entity_type;
|
||||
var l_entity_id = parentElement ? parentElement.dataset.entity_id : entity_id;
|
||||
var l_entity_name = parentElement ? parentElement.dataset.entity_name : entity_name;
|
||||
l_entity_id = parseInt(l_entity_id);
|
||||
|
||||
var entity_type = parentElement.dataset.entity_type;
|
||||
var entity_id = parentElement.dataset.entity_id;
|
||||
var entity_name = parentElement.dataset.entity_name;
|
||||
entity_id = parseInt(entity_id);
|
||||
|
||||
|
||||
const lcst = window.sessionStorage;
|
||||
var key = "marked_for_associate_" + l_entity_type;
|
||||
var current_stored = (lcst.getItem(key) || '').split(",");
|
||||
current_stored = current_stored.filter((x)=>x).map((x)=>parseInt(x));
|
||||
current_stored.push(l_entity_id);
|
||||
current_stored = [...new Set(current_stored)];
|
||||
lcst.setItem(key,current_stored); //this already formats it correctly
|
||||
var whattoadd = ((l_entity_type == 'track') ? "Artists or Album" : "Artists")
|
||||
notify("Marked " + l_entity_name + " to add " + whattoadd,"Currently " + current_stored.length + " marked!")
|
||||
if (!parentElement) {
|
||||
showValidMergeIcons();
|
||||
}
|
||||
else {
|
||||
toggleAssociationIcons(parentElement);
|
||||
}
|
||||
var key = "marked_for_associate_" + entity_type;
|
||||
var current_stored = getStoredList(key);
|
||||
current_stored.push(entity_id);
|
||||
storeList(key,current_stored);
|
||||
|
||||
notify("Marked " + entity_name + " to add to " + associate_targets[entity_type].join(" or "),"Currently " + current_stored.length + " marked!")
|
||||
|
||||
toggleAssociationIcons(parentElement);
|
||||
|
||||
}
|
||||
|
||||
function umarkForAssociate(element) {
|
||||
const parentElement = element.closest('[data-entity_id]');
|
||||
// use local element for entity data, otherwise use from global scope (on entity info page)
|
||||
var l_entity_type = parentElement ? parentElement.dataset.entity_type : entity_type;
|
||||
var l_entity_id = parentElement ? parentElement.dataset.entity_id : entity_id;
|
||||
var l_entity_name = parentElement ? parentElement.dataset.entity_name : entity_name;
|
||||
l_entity_id = parseInt(l_entity_id);
|
||||
|
||||
const lcst = window.sessionStorage;
|
||||
var key = "marked_for_associate_" + l_entity_type;
|
||||
var current_stored = (lcst.getItem(key) || '').split(",");
|
||||
current_stored = current_stored.filter((x)=>x).map((x)=>parseInt(x));
|
||||
var entity_type = parentElement.dataset.entity_type;
|
||||
var entity_id = parentElement.dataset.entity_id;
|
||||
var entity_name = parentElement.dataset.entity_name;
|
||||
entity_id = parseInt(entity_id);
|
||||
|
||||
if (current_stored.indexOf(l_entity_id) > -1) {
|
||||
current_stored.splice(current_stored.indexOf(l_entity_id),1);
|
||||
current_stored = [...new Set(current_stored)];
|
||||
lcst.setItem(key,current_stored); //this already formats it correctly
|
||||
var whattoadd = ((l_entity_type == 'track') ? "Artists or Album" : "Artists")
|
||||
notify("Unmarked " + l_entity_name + " to add " + whattoadd,"Currently " + current_stored.length + " marked!")
|
||||
if (!parentElement) {
|
||||
showValidMergeIcons();
|
||||
}
|
||||
else {
|
||||
toggleAssociationIcons(parentElement);
|
||||
}
|
||||
var key = "marked_for_associate_" + entity_type;
|
||||
var current_stored = getStoredList(key);
|
||||
|
||||
if (current_stored.indexOf(entity_id) > -1) {
|
||||
current_stored.splice(current_stored.indexOf(entity_id),1);
|
||||
storeList(key,current_stored);
|
||||
|
||||
notify("Unmarked " + entity_name + " from association with " + associate_targets[entity_type].join(" or "),"Currently " + current_stored.length + " marked!")
|
||||
|
||||
toggleAssociationIcons(parentElement);
|
||||
}
|
||||
else {
|
||||
notify(entity_name + " was not marked!","")
|
||||
//notify(entity_name + " was not marked!","")
|
||||
}
|
||||
|
||||
}
|
||||
@ -376,23 +307,78 @@ function toggleAssociationIcons(element) {
|
||||
var entity_id = element.dataset.entity_id;
|
||||
entity_id = parseInt(entity_id);
|
||||
|
||||
const lcst = window.sessionStorage;
|
||||
var key = "marked_for_associate_" + entity_type;
|
||||
var current_stored = (lcst.getItem(key) || '').split(",");
|
||||
current_stored = current_stored.filter((x)=>x).map((x)=>parseInt(x));
|
||||
var current_stored = getStoredList(key);
|
||||
|
||||
if (current_stored.indexOf(entity_id) > -1) {
|
||||
element.classList.add('marked');
|
||||
element.classList.add('marked_for_associate');
|
||||
} else {
|
||||
element.classList.remove('marked');
|
||||
element.classList.remove('marked_for_associate');
|
||||
}
|
||||
|
||||
if (current_stored.length > 0) {
|
||||
element.classList.add('somethingmarked_for_associate');
|
||||
}
|
||||
else {
|
||||
element.classList.remove('somethingmarked_for_associate');
|
||||
}
|
||||
|
||||
var sourcetypes = associate_sources[entity_type];
|
||||
var sourcelist = [];
|
||||
for (var src of sourcetypes) {
|
||||
var key = "marked_for_associate_" + src;
|
||||
sourcelist = sourcelist.concat(getStoredList(key));
|
||||
}
|
||||
if (sourcelist.length > 0) {
|
||||
element.classList.add('sources_marked_for_associate');
|
||||
}
|
||||
else {
|
||||
element.classList.remove('sources_marked_for_associate');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function toggleMergeIcons(element) {
|
||||
var entity_type = element.dataset.entity_type;
|
||||
var entity_id = element.dataset.entity_id;
|
||||
entity_id = parseInt(entity_id);
|
||||
|
||||
var key = "marked_for_merge_" + entity_type;
|
||||
var current_stored = getStoredList(key);
|
||||
|
||||
if (current_stored.indexOf(entity_id) > -1) {
|
||||
element.classList.add('marked_for_merge');
|
||||
} else {
|
||||
element.classList.remove('marked_for_merge');
|
||||
}
|
||||
|
||||
|
||||
if (current_stored.length > 0) {
|
||||
element.classList.add('somethingmarked_for_merge');
|
||||
}
|
||||
else {
|
||||
element.classList.remove('somethingmarked_for_merge');
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded',function(){
|
||||
var listrows = document.getElementsByClassName('listrow');
|
||||
for (var row of listrows) {
|
||||
toggleAssociationIcons(row);
|
||||
toggleMergeIcons(row); //just for the coloring, no icons
|
||||
}
|
||||
var topbars = document.getElementsByClassName('iconsubset');
|
||||
for (var bar of topbars) {
|
||||
toggleAssociationIcons(bar);
|
||||
toggleMergeIcons(bar);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
function merge() {
|
||||
const lcst = window.sessionStorage;
|
||||
var key = "marked_for_merge_" + entity_type;
|
||||
var current_stored = lcst.getItem(key).split(",");
|
||||
current_stored = current_stored.filter((x)=>x).map((x)=>parseInt(x));
|
||||
var current_stored = getStoredList(key);
|
||||
|
||||
callback_func = function(req){
|
||||
if (req.status == 200) {
|
||||
@ -415,26 +401,28 @@ function merge() {
|
||||
json=true
|
||||
);
|
||||
|
||||
lcst.removeItem(key);
|
||||
storeList(key,[]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function associate() {
|
||||
const lcst = window.sessionStorage;
|
||||
var target_entity_types = {artist:['album','track'], album:['track']};
|
||||
function associate(element) {
|
||||
const parentElement = element.closest('[data-entity_id]');
|
||||
var entity_type = parentElement.dataset.entity_type;
|
||||
var entity_id = parentElement.dataset.entity_id;
|
||||
entity_id = parseInt(entity_id);
|
||||
|
||||
var requests_todo = 0;
|
||||
for (var target_entity_type of target_entity_types[entity_type]) {
|
||||
for (var target_entity_type of associate_sources[entity_type]) {
|
||||
var key = "marked_for_associate_" + target_entity_type;
|
||||
var current_stored = (lcst.getItem(key) || '').split(",");
|
||||
current_stored = current_stored.filter((x)=>x).map((x)=>parseInt(x));
|
||||
var current_stored = getStoredList(key);
|
||||
|
||||
if (current_stored.length != 0) {
|
||||
requests_todo += 1;
|
||||
callback_func = function(req){
|
||||
if (req.status == 200) {
|
||||
|
||||
showValidMergeIcons();
|
||||
toggleAssociationIcons(parentElement);
|
||||
notifyCallback(req);
|
||||
requests_todo -= 1;
|
||||
if (requests_todo == 0) {
|
||||
@ -458,24 +446,30 @@ function associate() {
|
||||
json=true
|
||||
);
|
||||
|
||||
lcst.removeItem(key);
|
||||
storeList(key,[]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cancelMerge() {
|
||||
const lcst = window.sessionStorage;
|
||||
function cancelMerge(element) {
|
||||
const parentElement = element.closest('[data-entity_id]');
|
||||
|
||||
var entity_type = parentElement.dataset.entity_type;
|
||||
|
||||
var key = "marked_for_merge_" + entity_type;
|
||||
lcst.setItem(key,[]);
|
||||
showValidMergeIcons();
|
||||
notify("Cancelled merge!","")
|
||||
storeList(key,[])
|
||||
toggleMergeIcons(parentElement);
|
||||
notify("Cancelled " + entity_type + " merge!","")
|
||||
}
|
||||
function cancelAssociate() {
|
||||
const lcst = window.sessionStorage;
|
||||
function cancelAssociate(element) {
|
||||
const parentElement = element.closest('[data-entity_id]');
|
||||
|
||||
var entity_type = parentElement.dataset.entity_type;
|
||||
|
||||
var key = "marked_for_associate_" + entity_type;
|
||||
lcst.setItem(key,[]);
|
||||
showValidMergeIcons();
|
||||
notify("Cancelled association!","")
|
||||
storeList(key,[])
|
||||
toggleAssociationIcons(parentElement);
|
||||
notify("Cancelled " + entity_type + " association!","")
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user