Preferences.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. const { preferences } = res.data;
  92. if (res.status === "success") {
  93. this.localNightmode = preferences.nightmode;
  94. this.localAutoSkipDisliked = preferences.autoSkipDisliked;
  95. this.localActivityLogPublic = preferences.activityLogPublic;
  96. this.localAnonymousSongRequests =
  97. preferences.anonymousSongRequests;
  98. this.localActivityWatch = preferences.activityWatch;
  99. }
  100. });
  101. this.socket.on("keep.event:user.preferences.updated", res => {
  102. const { preferences } = res.data;
  103. this.localNightmode = preferences.nightmode;
  104. this.localAutoSkipDisliked = preferences.autoSkipDisliked;
  105. this.localActivityLogPublic = preferences.activityLogPublic;
  106. this.localAnonymousSongRequests = preferences.anonymousSongRequests;
  107. this.localActivityWatch = preferences.activityWatch;
  108. });
  109. },
  110. methods: {
  111. saveChanges() {
  112. if (
  113. this.localNightmode === this.nightmode &&
  114. this.localAutoSkipDisliked === this.autoSkipDisliked &&
  115. this.localActivityLogPublic === this.activityLogPublic &&
  116. this.localAnonymousSongRequests ===
  117. this.anonymousSongRequests &&
  118. this.localActivityWatch === this.activityWatch
  119. ) {
  120. new Toast("Please make a change before saving.");
  121. return this.$refs.saveButton.handleFailedSave();
  122. }
  123. this.$refs.saveButton.status = "disabled";
  124. return this.socket.dispatch(
  125. "users.updatePreferences",
  126. {
  127. nightmode: this.localNightmode,
  128. autoSkipDisliked: this.localAutoSkipDisliked,
  129. activityLogPublic: this.localActivityLogPublic,
  130. anonymousSongRequests: this.localAnonymousSongRequests,
  131. activityWatch: this.localActivityWatch
  132. },
  133. res => {
  134. if (res.status !== "success") {
  135. new Toast(res.message);
  136. return this.$refs.saveButton.handleFailedSave();
  137. }
  138. new Toast("Successfully updated preferences");
  139. return this.$refs.saveButton.handleSuccessfulSave();
  140. }
  141. );
  142. },
  143. ...mapActions("user/preferences", [
  144. "changeNightmode",
  145. "changeAutoSkipDisliked",
  146. "changeActivityLogPublic",
  147. "changeAnonymousSongRequests",
  148. "changeActivityWatch"
  149. ])
  150. }
  151. };
  152. </script>
  153. <style lang="scss" scoped>
  154. .checkbox-control {
  155. input[type="checkbox"] {
  156. opacity: 0;
  157. position: absolute;
  158. }
  159. label {
  160. display: flex;
  161. flex-direction: row;
  162. align-items: center;
  163. span {
  164. cursor: pointer;
  165. width: 24px;
  166. height: 24px;
  167. background-color: var(--white);
  168. display: inline-block;
  169. border: 1px solid var(--dark-grey-2);
  170. position: relative;
  171. border-radius: 3px;
  172. }
  173. p {
  174. margin-left: 10px;
  175. }
  176. }
  177. input[type="checkbox"]:checked + label span::after {
  178. content: "";
  179. width: 18px;
  180. height: 18px;
  181. left: 2px;
  182. top: 2px;
  183. border-radius: 3px;
  184. background-color: var(--primary-color);
  185. position: absolute;
  186. }
  187. }
  188. </style>