SettingsPage.vue 9.8 KB

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