media-control.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <template>
  2. <div class="media-control">
  3. <button-input ref="previousPage"
  4. type="transparent"
  5. title="previous page (Y)"
  6. style="color: var(--on_error)"
  7. :class="{disabled: !hasPreviousPage}"
  8. @click="$emit('previousPage', true)">
  9. <img alt="next" :class="{disabled: !hasPreviousPage}" src="@/assets/icons/double-chevron-left.svg">
  10. </button-input>
  11. <button-input ref="previousElement"
  12. type="transparent"
  13. title="previous element (A)"
  14. style="color: var(--on_error)"
  15. :class="{disabled: !hasPreviousElement}"
  16. @click="$emit('previousElement', true)">
  17. <img alt="next" :class="{disabled: !hasPreviousElement}" src="@/assets/icons/chevron-left.svg">
  18. </button-input>
  19. <select v-if="collections.length > 0"
  20. @change="filter">
  21. <option>no filter</option>
  22. <option>without collection</option>
  23. <option v-for="collection in collections" :key="collection.identifier"
  24. :value="collection.identifier"
  25. :selected="collection.autoselect">
  26. {{ collection.name }}
  27. </option>
  28. </select>
  29. <select v-else @change="only_annotations">
  30. <option>all images</option>
  31. <option>images with annotations</option>
  32. <option>images without annotations</option>
  33. </select>
  34. <button-input ref="nextElement"
  35. type="transparent"
  36. title="next element (D)"
  37. style="color: var(--on_error)"
  38. :class="{disabled: !hasNextElement}"
  39. @click="$emit('nextElement', true)">
  40. <img alt="next" :class="{disabled: !hasNextElement}" src="@/assets/icons/chevron-right.svg">
  41. </button-input>
  42. <button-input ref="nextPage"
  43. type="transparent"
  44. title="next page (C)"
  45. style="color: var(--on_error)"
  46. :class="{disabled: !hasNextPage}"
  47. @click="$emit('nextPage', true)">
  48. <img alt="next" :class="{disabled: !hasNextPage}" src="@/assets/icons/double-chevron-right.svg">
  49. </button-input>
  50. </div>
  51. </template>
  52. <script>
  53. import ButtonInput from "@/components/base/button-input";
  54. export default {
  55. name: "media-control",
  56. components: {ButtonInput},
  57. props: ['current', 'hasPreviousPage', 'hasNextPage', 'hasPreviousElement', 'hasNextElement'],
  58. created: function () {
  59. window.addEventListener('keypress', this.keypressEvent);
  60. // receive collections
  61. this.$root.socket.get(`/projects/${this.$root.project.identifier}/collections`)
  62. .then(response => response.json())
  63. .then(collections => {
  64. this.collections = collections;
  65. for (let collection of collections)
  66. if (collection.autoselect)
  67. this.$emit('filter', collection.identifier);
  68. });
  69. },
  70. destroyed: function () {
  71. window.removeEventListener('keypress', this.keypressEvent);
  72. },
  73. data: function () {
  74. return {
  75. collections: []
  76. }
  77. },
  78. methods: {
  79. keypressEvent: function (event) {
  80. switch (event.key) {
  81. case 'y':
  82. this.$refs.previousPage.click();
  83. break;
  84. case 'a':
  85. this.$refs.previousElement.click();
  86. break;
  87. case 'd':
  88. this.$refs.nextElement.click();
  89. break;
  90. case 'c':
  91. this.$refs.nextPage.click();
  92. break;
  93. }
  94. },
  95. filter: function (e) {
  96. const select = e.target;
  97. switch (select.selectedIndex) {
  98. // no filter
  99. case 0:
  100. this.$emit('filter', false);
  101. break;
  102. // without collection
  103. case 1:
  104. this.$emit('filter', null);
  105. break;
  106. // other
  107. default:
  108. this.$emit('filter', select.options[select.selectedIndex].value);
  109. break;
  110. }
  111. },
  112. only_annotations: function(e) {
  113. const select = e.target;
  114. switch (select.selectedIndex) {
  115. // no filter
  116. case 0:
  117. this.$emit('only_annotations', null);
  118. break;
  119. // only with annotations
  120. case 1:
  121. this.$emit('only_annotations', true);
  122. break;
  123. // only without annotations
  124. default:
  125. this.$emit('only_annotations', false);
  126. break;
  127. }
  128. }
  129. }
  130. }
  131. </script>
  132. <style scoped>
  133. .media-control {
  134. background-color: rgba(0, 0, 0, 0.75);
  135. color: whitesmoke;
  136. display: flex;
  137. flex-direction: row;
  138. justify-content: center;
  139. align-items: center;
  140. }
  141. .button-input {
  142. font-size: 110%;
  143. font-weight: bold;
  144. }
  145. .disabled {
  146. opacity: 0.4;
  147. }
  148. img {
  149. filter: invert(1);
  150. }
  151. img.disabled {
  152. filter: invert(1);
  153. background-color: transparent;
  154. }
  155. select {
  156. flex-grow: 1;
  157. max-width: 15rem;
  158. margin: 0 1rem;
  159. }
  160. </style>