CreatePlaylist.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. <template>
  2. <modal title="Create Playlist">
  3. <template #body>
  4. <p class="control is-expanded">
  5. <label class="label">Display Name</label>
  6. <input
  7. v-model="playlist.displayName"
  8. class="input"
  9. type="text"
  10. placeholder="Enter display name..."
  11. autofocus
  12. @keyup.enter="createPlaylist()"
  13. />
  14. </p>
  15. <div class="control" id="privacy-selection">
  16. <label class="label">Privacy</label>
  17. <p class="control select">
  18. <select v-model="playlist.privacy">
  19. <option value="private">Private</option>
  20. <option value="public" selected>Public</option>
  21. </select>
  22. </p>
  23. </div>
  24. </template>
  25. <template #footer>
  26. <a class="button is-info" @click="createPlaylist()"
  27. ><i class="material-icons icon-with-button">create</i>Create
  28. Playlist</a
  29. >
  30. </template>
  31. </modal>
  32. </template>
  33. <script>
  34. import { mapActions } from "vuex";
  35. import Toast from "toasters";
  36. import Modal from "../Modal.vue";
  37. import io from "../../io";
  38. import validation from "../../validation";
  39. export default {
  40. components: { Modal },
  41. data() {
  42. return {
  43. playlist: {
  44. displayName: "",
  45. privacy: "public",
  46. songs: []
  47. }
  48. };
  49. },
  50. mounted() {
  51. io.getSocket(socket => {
  52. this.socket = socket;
  53. });
  54. },
  55. methods: {
  56. createPlaylist() {
  57. const { displayName } = this.playlist;
  58. if (!validation.isLength(displayName, 2, 32))
  59. return new Toast({
  60. content:
  61. "Display name must have between 2 and 32 characters.",
  62. timeout: 8000
  63. });
  64. if (!validation.regex.ascii.test(displayName))
  65. return new Toast({
  66. content:
  67. "Invalid display name format. Only ASCII characters are allowed.",
  68. timeout: 8000
  69. });
  70. return this.socket.emit("playlists.create", this.playlist, res => {
  71. new Toast({ content: res.message, timeout: 3000 });
  72. if (res.status === "success") {
  73. this.closeModal({
  74. sector: "station",
  75. modal: "createPlaylist"
  76. });
  77. this.editPlaylist(res.data._id);
  78. this.openModal({
  79. sector: "station",
  80. modal: "editPlaylist"
  81. });
  82. }
  83. });
  84. },
  85. ...mapActions("modalVisibility", ["closeModal", "openModal"]),
  86. ...mapActions("user/playlists", ["editPlaylist"])
  87. }
  88. };
  89. </script>
  90. <style lang="scss" scoped>
  91. @import "../../styles/global.scss";
  92. .menu {
  93. padding: 0 20px;
  94. }
  95. .menu-list li {
  96. display: flex;
  97. justify-content: space-between;
  98. }
  99. .menu-list a:hover {
  100. color: $black !important;
  101. }
  102. li a {
  103. display: flex;
  104. align-items: center;
  105. }
  106. #privacy-selection {
  107. margin-top: 15px;
  108. }
  109. .controls {
  110. display: flex;
  111. a {
  112. display: flex;
  113. align-items: center;
  114. }
  115. }
  116. .label {
  117. font-size: 1rem;
  118. }
  119. </style>