PlaylistItem.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <template>
  2. <div class="playlist-item universal-item">
  3. <slot name="item-icon" />
  4. <div class="item-title-description">
  5. <p class="item-title">
  6. {{ playlist.displayName }}
  7. <i
  8. v-if="playlist.privacy === 'private'"
  9. class="private-playlist-icon material-icons"
  10. content="This playlist is not visible to other users."
  11. v-tippy="{ theme: 'info' }"
  12. >lock</i
  13. >
  14. </p>
  15. <p class="item-description">
  16. <span v-if="showOwner"
  17. ><a v-if="playlist.createdBy === 'Musare'" title="Musare"
  18. >Musare</a
  19. ><user-id-to-username
  20. v-else
  21. :user-id="playlist.createdBy"
  22. :link="true"
  23. />
  24. •</span
  25. >
  26. <span :title="playlistLength">
  27. {{ playlistLength }}
  28. </span>
  29. </p>
  30. </div>
  31. <div class="universal-item-actions">
  32. <slot name="actions" />
  33. </div>
  34. </div>
  35. </template>
  36. <script>
  37. import UserIdToUsername from "@/components/UserIdToUsername.vue";
  38. import utils from "../../js/utils";
  39. export default {
  40. components: { UserIdToUsername },
  41. props: {
  42. playlist: { type: Object, default: () => {} },
  43. showOwner: { type: Boolean, default: false }
  44. },
  45. data() {
  46. return {
  47. utils
  48. };
  49. },
  50. computed: {
  51. playlistLength() {
  52. return `${this.totalLength(this.playlist)} • ${
  53. this.playlist.songs.length
  54. } ${this.playlist.songs.length === 1 ? "song" : "songs"}`;
  55. }
  56. },
  57. methods: {
  58. totalLength(playlist) {
  59. let length = 0;
  60. playlist.songs.forEach(song => {
  61. length += song.duration;
  62. });
  63. return this.utils.formatTimeLong(length);
  64. }
  65. }
  66. };
  67. </script>
  68. <style lang="scss" scoped>
  69. .night-mode {
  70. .playlist-item {
  71. background-color: var(--dark-grey-2) !important;
  72. border: 0 !important;
  73. p {
  74. color: var(--light-grey-2) !important;
  75. }
  76. }
  77. }
  78. .playlist-item {
  79. width: 100%;
  80. height: 72px;
  81. column-gap: 7.5px;
  82. .item-title-description {
  83. flex: 1;
  84. overflow: hidden;
  85. .item-title {
  86. color: var(--dark-grey-2);
  87. font-size: 20px;
  88. line-height: 23px;
  89. margin-bottom: 0;
  90. display: flex;
  91. align-items: center;
  92. .private-playlist-icon {
  93. color: var(--dark-pink);
  94. font-size: 18px;
  95. margin-left: 5px;
  96. }
  97. }
  98. }
  99. .universal-item-actions {
  100. margin-left: none;
  101. div {
  102. display: flex;
  103. align-items: center;
  104. line-height: 1;
  105. button,
  106. .button {
  107. width: 100%;
  108. font-size: 17px;
  109. height: 36px;
  110. }
  111. }
  112. }
  113. }
  114. </style>