SettingsPage.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <template>
  2. <Window ref="window" width="600px" @close="close">
  3. <template #header>
  4. Настройки
  5. </template>
  6. <div class="col row">
  7. <div class="full-height">
  8. <q-tabs
  9. ref="tabs"
  10. v-model="selectedTab"
  11. class="bg-grey-3 text-grey-9"
  12. style="max-width: 130px"
  13. left-icon="la la-caret-up"
  14. right-icon="la la-caret-down"
  15. active-color="white"
  16. active-bg-color="primary"
  17. indicator-color="black"
  18. vertical
  19. no-caps
  20. stretch
  21. inline-label
  22. >
  23. <q-tab v-for="item in tabs" :key="item.name" class="tab row items-center" :name="item.name">
  24. <q-icon :name="item.icon" :color="selectedTab == item.name ? 'yellow' : 'teal-7'" size="24px" />
  25. <div class="q-ml-xs" style="font-size: 90%">
  26. {{ item.label }}
  27. </div>
  28. </q-tab>
  29. </q-tabs>
  30. </div>
  31. <div class="col fit">
  32. <!-- Профили --------------------------------------------------------------------->
  33. <ProfilesTab v-if="selectedTab == 'profiles'" :form="form" />
  34. <!-- Вид ------------------------------------------------------------------------->
  35. <ViewTab v-if="selectedTab == 'view'" :form="form" />
  36. <!-- Кнопки ---------------------------------------------------------------------->
  37. <ToolBarTab v-if="selectedTab == 'toolbar'" :form="form" />
  38. <!-- Управление ------------------------------------------------------------------>
  39. <KeysTab v-if="selectedTab == 'keys'" :form="form" />
  40. <!-- Листание -------------------------------------------------------------------->
  41. <PageMoveTab v-if="selectedTab == 'pagemove'" :form="form" />
  42. <!-- Конвертирование ------------------------------------------------------------->
  43. <ConvertTab v-if="selectedTab == 'convert'" :form="form" />
  44. <!-- Обновление ------------------------------------------------------------------>
  45. <UpdateTab v-if="selectedTab == 'update'" :form="form" />
  46. <!-- Прочее ---------------------------------------------------------------------->
  47. <OthersTab v-if="selectedTab == 'others'" :form="form" />
  48. <!-- Сброс ----------------------------------------------------------------------->
  49. <ResetTab v-if="selectedTab == 'reset'" :form="form" @tab-event="tabEvent" />
  50. </div>
  51. </div>
  52. </Window>
  53. </template>
  54. <script>
  55. //-----------------------------------------------------------------------------
  56. import vueComponent from '../../vueComponent.js';
  57. import { reactive } from 'vue';
  58. import _ from 'lodash';
  59. //stuff
  60. import Window from '../../share/Window.vue';
  61. import rstore from '../../../store/modules/reader';
  62. //pages
  63. import ProfilesTab from './ProfilesTab/ProfilesTab.vue';
  64. import ViewTab from './ViewTab/ViewTab.vue';
  65. import ToolBarTab from './ToolBarTab/ToolBarTab.vue';
  66. import KeysTab from './KeysTab/KeysTab.vue';
  67. import PageMoveTab from './PageMoveTab/PageMoveTab.vue';
  68. import ConvertTab from './ConvertTab/ConvertTab.vue';
  69. import UpdateTab from './UpdateTab/UpdateTab.vue';
  70. import OthersTab from './OthersTab/OthersTab.vue';
  71. import ResetTab from './ResetTab/ResetTab.vue';
  72. const hex = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/;
  73. const componentOptions = {
  74. components: {
  75. Window,
  76. //pages
  77. ProfilesTab,
  78. ViewTab,
  79. ToolBarTab,
  80. KeysTab,
  81. PageMoveTab,
  82. ConvertTab,
  83. UpdateTab,
  84. OthersTab,
  85. ResetTab,
  86. },
  87. watch: {
  88. settings: function() {
  89. this.settingsChanged();//no await
  90. },
  91. form: {
  92. handler() {
  93. if (this.inited && !this.isSetsChanged) {
  94. this.debouncedCommitSettings();
  95. }
  96. },
  97. deep: true,
  98. },
  99. statusBarColor(newValue) {
  100. this.statusBarColorFiltered = newValue;
  101. },
  102. statusBarColorFiltered(newValue) {
  103. if (hex.test(newValue))
  104. this.statusBarColor = newValue;
  105. },
  106. },
  107. };
  108. class SettingsPage {
  109. _options = componentOptions;
  110. form = {};
  111. tabs = [
  112. { name: 'profiles', icon: 'la la-users', label: 'Профили' },
  113. { name: 'view', icon: 'la la-eye', label: 'Вид'},
  114. { name: 'toolbar', icon: 'la la-grip-horizontal', label: 'Панель'},
  115. { name: 'keys', icon: 'la la-gamepad', label: 'Управление'},
  116. { name: 'pagemove', icon: 'la la-school', label: 'Листание'},
  117. { name: 'convert', icon: 'la la-magic', label: 'Конвертир.'},
  118. { name: 'update', icon: 'la la-retweet', label: 'Обновление'},
  119. { name: 'others', icon: 'la la-list-ul', label: 'Прочее'},
  120. { name: 'reset', icon: 'la la-broom', label: 'Сброс'},
  121. ];
  122. selectedTab = 'profiles';
  123. isSetsChanged = false;
  124. statusBarColorFiltered = '';
  125. created() {
  126. this.commit = this.$store.commit;
  127. this.debouncedCommitSettings = _.debounce(() => {
  128. this.commit('reader/setSettings', _.cloneDeep(this.form));
  129. }, 50);
  130. this.settingsChanged();//no await
  131. }
  132. mounted() {
  133. }
  134. init() {
  135. this.$refs.window.init();
  136. this.inited = true;
  137. }
  138. async settingsChanged() {
  139. this.isSetsChanged = true;
  140. try {
  141. this.form = reactive(_.cloneDeep(this.settings));
  142. const form = this.form;
  143. this.statusBarColorFiltered = form.statusBarColor;
  144. } finally {
  145. await this.$nextTick();
  146. this.isSetsChanged = false;
  147. }
  148. }
  149. get settings() {
  150. return this.$store.state.reader.settings;
  151. }
  152. needReload() {
  153. this.$root.notify.warning('Необходимо обновить страницу (F5), чтобы изменения возымели эффект');
  154. }
  155. close() {
  156. this.$emit('do-action', {action: 'settings'});
  157. }
  158. async setDefaults() {
  159. try {
  160. if (await this.$root.stdDialog.confirm('Подтвердите установку настроек по умолчанию:', ' ')) {
  161. this.form = _.cloneDeep(rstore.settingDefaults);
  162. }
  163. } catch (e) {
  164. //
  165. }
  166. }
  167. tabEvent(event) {
  168. if (!event || !event.action)
  169. return;
  170. switch (event.action) {
  171. case 'set-defaults': this.setDefaults(); break;
  172. }
  173. }
  174. keyHook(event) {
  175. if (!this.$root.stdDialog.active && event.type == 'keydown' && event.key == 'Escape') {
  176. this.close();
  177. }
  178. return true;
  179. }
  180. }
  181. export default vueComponent(SettingsPage);
  182. //-----------------------------------------------------------------------------
  183. </script>
  184. <style scoped>
  185. .tab {
  186. justify-content: initial;
  187. }
  188. </style>
  189. <style>
  190. .sets-tab-panel {
  191. overflow-x: hidden;
  192. overflow-y: auto;
  193. font-size: 90%;
  194. padding: 0 10px 15px 10px;
  195. }
  196. .sets-part-header {
  197. border-top: 2px solid #bbbbbb;
  198. font-weight: bold;
  199. font-size: 110%;
  200. margin-top: 15px;
  201. margin-bottom: 5px;
  202. }
  203. .sets-label {
  204. display: flex;
  205. flex-direction: column;
  206. justify-content: center;
  207. text-align: right;
  208. margin-right: 10px;
  209. overflow: hidden;
  210. }
  211. .sets-item {
  212. width: 100%;
  213. margin-top: 5px;
  214. margin-bottom: 5px;
  215. }
  216. .sets-button {
  217. margin: 3px 15px 3px 0;
  218. padding: 0 5px 0 5px;
  219. }
  220. </style>