Preferences.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <template>
  2. <div class="content preferences-tab">
  3. <h4 class="section-title">Change preferences</h4>
  4. <p class="section-description">Tailor these settings to your liking.</p>
  5. <hr class="section-horizontal-rule" />
  6. <p class="control is-expanded checkbox-control">
  7. <input type="checkbox" id="nightmode" v-model="localNightmode" />
  8. <label for="nightmode">
  9. <span></span>
  10. <p>Use nightmode</p>
  11. </label>
  12. </p>
  13. <p class="control is-expanded checkbox-control">
  14. <input
  15. type="checkbox"
  16. id="autoSkipDisliked"
  17. v-model="localAutoSkipDisliked"
  18. />
  19. <label for="autoSkipDisliked">
  20. <span></span>
  21. <p>Automatically vote to skip disliked songs</p>
  22. </label>
  23. </p>
  24. <p class="control is-expanded checkbox-control">
  25. <input
  26. type="checkbox"
  27. id="activityLogPublic"
  28. v-model="localActivityLogPublic"
  29. />
  30. <label for="activityLogPublic">
  31. <span></span>
  32. <p>Allow my activity log to be viewed publicly</p>
  33. </label>
  34. </p>
  35. <p class="control is-expanded checkbox-control">
  36. <input
  37. type="checkbox"
  38. id="anonymousSongRequests"
  39. v-model="localAnonymousSongRequests"
  40. />
  41. <label for="anonymousSongRequests">
  42. <span></span>
  43. <p>Request songs anonymously</p>
  44. </label>
  45. </p>
  46. <p class="control is-expanded checkbox-control">
  47. <input
  48. type="checkbox"
  49. id="activityWatch"
  50. v-model="localActivityWatch"
  51. />
  52. <label for="activityWatch">
  53. <span></span>
  54. <p>Use ActivityWatch integration (requires extension)</p>
  55. </label>
  56. </p>
  57. <save-button ref="saveButton" @clicked="saveChanges()" />
  58. </div>
  59. </template>
  60. <script>
  61. import { mapState, mapActions, mapGetters } from "vuex";
  62. import Toast from "toasters";
  63. import SaveButton from "@/components/SaveButton.vue";
  64. export default {
  65. components: { SaveButton },
  66. data() {
  67. return {
  68. localNightmode: false,
  69. localAutoSkipDisliked: false,
  70. localActivityLogPublic: false,
  71. localAnonymousSongRequests: false,
  72. localActivityWatch: false
  73. };
  74. },
  75. computed: {
  76. ...mapState({
  77. nightmode: state => state.user.preferences.nightmode,
  78. autoSkipDisliked: state => state.user.preferences.autoSkipDisliked,
  79. activityLogPublic: state =>
  80. state.user.preferences.activityLogPublic,
  81. anonymousSongRequests: state =>
  82. state.user.preferences.anonymousSongRequests,
  83. activityWatch: state => state.user.preferences.activityWatch
  84. }),
  85. ...mapGetters({
  86. socket: "websockets/getSocket"
  87. })
  88. },
  89. mounted() {
  90. this.socket.dispatch("users.getPreferences", res => {
  91. if (res.status === "success") {
  92. this.localNightmode = res.data.nightmode;
  93. this.localAutoSkipDisliked = res.data.autoSkipDisliked;
  94. this.localActivityLogPublic = res.data.activityLogPublic;
  95. this.localAnonymousSongRequests =
  96. res.data.anonymousSongRequests;
  97. this.localActivityWatch = res.data.activityWatch;
  98. }
  99. });
  100. this.socket.on("keep.event:user.preferences.changed", preferences => {
  101. this.localNightmode = preferences.nightmode;
  102. this.localAutoSkipDisliked = preferences.autoSkipDisliked;
  103. this.localActivityLogPublic = preferences.activityLogPublic;
  104. this.localAnonymousSongRequests = preferences.anonymousSongRequests;
  105. this.localActivityWatch = preferences.activityWatch;
  106. });
  107. },
  108. methods: {
  109. saveChanges() {
  110. if (
  111. this.localNightmode === this.nightmode &&
  112. this.localAutoSkipDisliked === this.autoSkipDisliked &&
  113. this.localActivityLogPublic === this.activityLogPublic &&
  114. this.localAnonymousSongRequests ===
  115. this.anonymousSongRequests &&
  116. this.localActivityWatch === this.activityWatch
  117. ) {
  118. new Toast("Please make a change before saving.");
  119. return this.$refs.saveButton.handleFailedSave();
  120. }
  121. this.$refs.saveButton.status = "disabled";
  122. return this.socket.dispatch(
  123. "users.updatePreferences",
  124. {
  125. nightmode: this.localNightmode,
  126. autoSkipDisliked: this.localAutoSkipDisliked,
  127. activityLogPublic: this.localActivityLogPublic,
  128. anonymousSongRequests: this.localAnonymousSongRequests,
  129. activityWatch: this.localActivityWatch
  130. },
  131. res => {
  132. if (res.status !== "success") {
  133. new Toast(res.message);
  134. return this.$refs.saveButton.handleFailedSave();
  135. }
  136. new Toast("Successfully updated preferences");
  137. return this.$refs.saveButton.handleSuccessfulSave();
  138. }
  139. );
  140. },
  141. ...mapActions("user/preferences", [
  142. "changeNightmode",
  143. "changeAutoSkipDisliked",
  144. "changeActivityLogPublic",
  145. "changeAnonymousSongRequests",
  146. "changeActivityWatch"
  147. ])
  148. }
  149. };
  150. </script>
  151. <style lang="scss" scoped>
  152. .checkbox-control {
  153. input[type="checkbox"] {
  154. opacity: 0;
  155. position: absolute;
  156. }
  157. label {
  158. display: flex;
  159. flex-direction: row;
  160. align-items: center;
  161. span {
  162. cursor: pointer;
  163. width: 24px;
  164. height: 24px;
  165. background-color: var(--white);
  166. display: inline-block;
  167. border: 1px solid var(--dark-grey-2);
  168. position: relative;
  169. border-radius: 3px;
  170. }
  171. p {
  172. margin-left: 10px;
  173. }
  174. }
  175. input[type="checkbox"]:checked + label span::after {
  176. content: "";
  177. width: 18px;
  178. height: 18px;
  179. left: 2px;
  180. top: 2px;
  181. border-radius: 3px;
  182. background-color: var(--primary-color);
  183. position: absolute;
  184. }
  185. }
  186. </style>