mirror of
https://github.com/requarks/wiki.git
synced 2026-08-26 13:17:10 -05:00
feat: accessibilty cvd option + editor page header
This commit is contained in:
@@ -691,7 +691,8 @@ exports.up = async knex => {
|
||||
timezone: 'America/New_York',
|
||||
dateFormat: 'YYYY-MM-DD',
|
||||
timeFormat: '12h',
|
||||
appearance: 'site'
|
||||
appearance: 'site',
|
||||
cvd: 'none'
|
||||
},
|
||||
localeCode: 'en'
|
||||
},
|
||||
@@ -708,7 +709,8 @@ exports.up = async knex => {
|
||||
timezone: 'America/New_York',
|
||||
dateFormat: 'YYYY-MM-DD',
|
||||
timeFormat: '12h',
|
||||
appearance: 'site'
|
||||
appearance: 'site',
|
||||
cvd: 'none'
|
||||
},
|
||||
localeCode: 'en'
|
||||
}
|
||||
|
||||
@@ -229,7 +229,8 @@ module.exports = {
|
||||
timezone: args.timezone || usr.prefs.timezone,
|
||||
dateFormat: args.dateFormat ?? usr.prefs.dateFormat,
|
||||
timeFormat: args.timeFormat ?? usr.prefs.timeFormat,
|
||||
appearance: args.appearance || usr.prefs.appearance
|
||||
appearance: args.appearance || usr.prefs.appearance,
|
||||
cvd: args.cvd || usr.prefs.cvd
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ extend type Mutation {
|
||||
dateFormat: String
|
||||
timeFormat: String
|
||||
appearance: UserSiteAppearance
|
||||
cvd: UserCvdChoices
|
||||
): DefaultResponse
|
||||
|
||||
uploadUserAvatar(
|
||||
@@ -154,6 +155,13 @@ enum UserSiteAppearance {
|
||||
dark
|
||||
}
|
||||
|
||||
enum UserCvdChoices {
|
||||
none
|
||||
protanopia
|
||||
deuteranopia
|
||||
tritanopia
|
||||
}
|
||||
|
||||
input UserUpdateInput {
|
||||
email: String
|
||||
name: String
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" width="80px" height="80px"><path fill="#fff" d="M20,32.5C10.238,32.5,2.002,21.886,0.616,20C2.002,18.115,10.245,7.5,20,7.5 c9.762,0,17.998,10.614,19.384,12.5C37.998,21.885,29.755,32.5,20,32.5z"/><path fill="#4788c7" d="M20,8c9.097,0,16.906,9.549,18.76,12C36.908,22.453,29.11,32,20,32c-9.097,0-16.906-9.549-18.76-12 C3.092,17.547,10.89,8,20,8 M20,7C8.954,7,0,20,0,20s8.954,13,20,13s20-13,20-13S31.046,7,20,7L20,7z"/><path fill="#98ccfd" d="M25.994 26.701C27.835 25.053 29 22.665 29 20c0-4.971-4.029-9-9-9-2.665 0-5.053 1.165-6.701 3.006L25.994 26.701zM8.166 12.873L25.98 30.687c.329-.139.654-.284.974-.44l-17.99-17.99C8.693 12.46 8.428 12.666 8.166 12.873zM6.019 14.726l16.932 16.932c.378-.082.751-.182 1.123-.291L6.757 14.05C6.501 14.276 6.261 14.501 6.019 14.726zM4.707 16c-.242.247-.468.486-.69.724l15.228 15.228C19.497 31.966 19.746 32 20 32c.224 0 .443-.031.665-.042L4.707 16zM2.145 18.852l11.803 11.803c.713.305 1.442.564 2.187.773L2.791 18.084C2.557 18.357 2.341 18.614 2.145 18.852z"/><path fill="#4788c7" d="M22.441,23.148C23.383,22.416,24,21.285,24,20c0-2.209-1.791-4-4-4c-1.285,0-2.416,0.617-3.148,1.559 L22.441,23.148z"/><path fill="#dff0fe" d="M23 14A2 2 0 1 0 23 18A2 2 0 1 0 23 14Z"/><path fill="none" stroke="#4788c7" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M3 3L37 37"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
+11
-5
@@ -42,6 +42,10 @@ watch(() => userStore.appearance, (newValue) => {
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => userStore.cvd, () => {
|
||||
applyTheme()
|
||||
})
|
||||
|
||||
// THEME
|
||||
|
||||
function applyTheme () {
|
||||
@@ -50,11 +54,13 @@ function applyTheme () {
|
||||
} else {
|
||||
$q.dark.set(userStore.appearance === 'dark')
|
||||
}
|
||||
setCssVar('primary', siteStore.theme.colorPrimary)
|
||||
setCssVar('secondary', siteStore.theme.colorSecondary)
|
||||
setCssVar('accent', siteStore.theme.colorAccent)
|
||||
setCssVar('header', siteStore.theme.colorHeader)
|
||||
setCssVar('sidebar', siteStore.theme.colorSidebar)
|
||||
setCssVar('primary', userStore.getAccessibleColor('primary', siteStore.theme.colorPrimary))
|
||||
setCssVar('secondary', userStore.getAccessibleColor('secondary', siteStore.theme.colorSecondary))
|
||||
setCssVar('accent', userStore.getAccessibleColor('accent', siteStore.theme.colorAccent))
|
||||
setCssVar('header', userStore.getAccessibleColor('header', siteStore.theme.colorHeader))
|
||||
setCssVar('sidebar', userStore.getAccessibleColor('sidebar', siteStore.theme.colorSidebar))
|
||||
setCssVar('positive', userStore.getAccessibleColor('positive', '#02C39A'))
|
||||
setCssVar('negative', userStore.getAccessibleColor('negative', '#f03a47'))
|
||||
}
|
||||
|
||||
// INIT SITE STORE
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
flat
|
||||
)
|
||||
q-tooltip(anchor='center right' self='center left') {{ t('editor.markup.horizontalBar') }}
|
||||
.editor-markdown-editor
|
||||
.editor-markdown-mid
|
||||
//--------------------------------------------------------
|
||||
//- TOP TOOLBAR
|
||||
//--------------------------------------------------------
|
||||
@@ -115,9 +115,11 @@
|
||||
//--------------------------------------------------------
|
||||
//- CODEMIRROR
|
||||
//--------------------------------------------------------
|
||||
textarea(ref='cmRef')
|
||||
.editor-markdown-editor
|
||||
textarea(ref='cmRef')
|
||||
transition(name='editor-markdown-preview')
|
||||
.editor-markdown-preview(v-if='state.previewShown')
|
||||
.editor-markdown-preview-toolbar Render Preview
|
||||
.editor-markdown-preview-content.contents(ref='editorPreviewContainer')
|
||||
div(
|
||||
ref='editorPreview'
|
||||
@@ -126,7 +128,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, shallowRef, onBeforeMount, onMounted, watch } from 'vue'
|
||||
import { reactive, ref, shallowRef, nextTick, onBeforeMount, onMounted, watch } from 'vue'
|
||||
import { useMeta, useQuasar, setCssVar } from 'quasar'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
@@ -169,6 +171,7 @@ const cm = shallowRef(null)
|
||||
const cmRef = ref(null)
|
||||
|
||||
const state = reactive({
|
||||
content: '',
|
||||
previewShown: true,
|
||||
previewHTML: ''
|
||||
})
|
||||
@@ -212,7 +215,7 @@ onMounted(async () => {
|
||||
// onCmInput(editorStore.content)
|
||||
})
|
||||
|
||||
cm.value.setSize(null, 'calc(100vh - 150px)')
|
||||
cm.value.setSize(null, '100%')
|
||||
|
||||
// -> Set Keybindings
|
||||
const keyBindings = {
|
||||
@@ -263,7 +266,9 @@ onMounted(async () => {
|
||||
|
||||
// // Render initial preview
|
||||
// this.processContent(this.$store.get('editor/content'))
|
||||
// this.refresh()
|
||||
nextTick(() => {
|
||||
cm.value.refresh()
|
||||
})
|
||||
|
||||
// this.$root.$on('editorInsert', opts => {
|
||||
// switch (opts.kind) {
|
||||
@@ -306,7 +311,7 @@ onBeforeMount(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
$editor-height: calc(100vh - 112px - 24px);
|
||||
$editor-height: calc(100vh - 64px - 94px - 2px);
|
||||
$editor-height-mobile: calc(100vh - 112px - 16px);
|
||||
|
||||
.editor-markdown {
|
||||
@@ -314,12 +319,17 @@ $editor-height-mobile: calc(100vh - 112px - 16px);
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
&-editor {
|
||||
&-mid {
|
||||
background-color: $dark-6;
|
||||
flex: 1 1 50%;
|
||||
display: block;
|
||||
height: $editor-height;
|
||||
position: relative;
|
||||
}
|
||||
&-editor {
|
||||
display: block;
|
||||
height: calc(100% - 32px);
|
||||
position: relative;
|
||||
// @include until($tablet) {
|
||||
// height: $editor-height-mobile;
|
||||
// }
|
||||
@@ -330,8 +340,6 @@ $editor-height-mobile: calc(100vh - 112px - 16px);
|
||||
position: relative;
|
||||
height: $editor-height;
|
||||
overflow: hidden;
|
||||
padding: 1rem;
|
||||
border-top: 32px solid $grey-3;
|
||||
|
||||
@at-root .theme--dark & {
|
||||
background-color: $grey-9;
|
||||
@@ -350,10 +358,18 @@ $editor-height-mobile: calc(100vh - 112px - 16px);
|
||||
&-enter, &-leave-to {
|
||||
max-width: 0;
|
||||
}
|
||||
&-toolbar {
|
||||
background-color: $grey-3;
|
||||
color: $grey-8;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
&-content {
|
||||
height: $editor-height;
|
||||
overflow-y: scroll;
|
||||
padding: 0;
|
||||
padding: 1rem;
|
||||
width: calc(100% + 17px);
|
||||
// -ms-overflow-style: none;
|
||||
// &::-webkit-scrollbar {
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
<template lang="pug">
|
||||
.page-header.row
|
||||
//- PAGE ICON
|
||||
.col-auto.q-pl-md.flex.items-center
|
||||
q-btn.rounded-borders(
|
||||
v-if='editorStore.isActive'
|
||||
padding='none'
|
||||
size='37px'
|
||||
:icon='pageStore.icon'
|
||||
color='primary'
|
||||
flat
|
||||
)
|
||||
q-menu(content-class='shadow-7')
|
||||
icon-picker-dialog(v-model='pageStore.icon')
|
||||
q-icon.rounded-borders(
|
||||
v-else
|
||||
:name='pageStore.icon'
|
||||
size='64px'
|
||||
color='primary'
|
||||
)
|
||||
//- PAGE HEADER
|
||||
.col.q-pa-md
|
||||
.text-h4.page-header-title
|
||||
span {{pageStore.title}}
|
||||
template(v-if='editorStore.isActive')
|
||||
span.text-grey(v-if='!pageStore.title') {{ t(`editor.props.title`)}}
|
||||
q-btn.acrylic-btn.q-ml-md(
|
||||
icon='las la-pen'
|
||||
flat
|
||||
padding='xs'
|
||||
size='sm'
|
||||
)
|
||||
q-popup-edit(
|
||||
v-model='pageStore.title'
|
||||
auto-save
|
||||
v-slot='scope'
|
||||
)
|
||||
q-input(
|
||||
outlined
|
||||
style='width: 450px;'
|
||||
v-model='scope.value'
|
||||
dense
|
||||
autofocus
|
||||
@keyup.enter='scope.set'
|
||||
:label='t(`editor.props.title`)'
|
||||
)
|
||||
.text-subtitle2.page-header-subtitle
|
||||
span {{ pageStore.description }}
|
||||
template(v-if='editorStore.isActive')
|
||||
span.text-grey(v-if='!pageStore.description') {{ t(`editor.props.shortDescription`)}}
|
||||
q-btn.acrylic-btn.q-ml-md(
|
||||
icon='las la-pen'
|
||||
flat
|
||||
padding='none xs'
|
||||
size='xs'
|
||||
)
|
||||
q-popup-edit(
|
||||
v-model='pageStore.description'
|
||||
auto-save
|
||||
v-slot='scope'
|
||||
)
|
||||
q-input(
|
||||
outlined
|
||||
style='width: 450px;'
|
||||
v-model='scope.value'
|
||||
dense
|
||||
autofocus
|
||||
@keyup.enter='scope.set'
|
||||
:label='t(`editor.props.shortDescription`)'
|
||||
)
|
||||
//- PAGE ACTIONS
|
||||
.col-auto.q-pa-md.flex.items-center.justify-end
|
||||
template(v-if='!editorStore.isActive')
|
||||
q-btn.q-mr-md(
|
||||
flat
|
||||
dense
|
||||
icon='las la-bell'
|
||||
color='grey'
|
||||
aria-label='Watch Page'
|
||||
)
|
||||
q-tooltip Watch Page
|
||||
q-btn.q-mr-md(
|
||||
flat
|
||||
dense
|
||||
icon='las la-bookmark'
|
||||
color='grey'
|
||||
aria-label='Bookmark Page'
|
||||
)
|
||||
q-tooltip Bookmark Page
|
||||
q-btn.q-mr-md(
|
||||
flat
|
||||
dense
|
||||
icon='las la-share-alt'
|
||||
color='grey'
|
||||
aria-label='Share'
|
||||
)
|
||||
q-tooltip Share
|
||||
social-sharing-menu
|
||||
q-btn.q-mr-md(
|
||||
flat
|
||||
dense
|
||||
icon='las la-print'
|
||||
color='grey'
|
||||
aria-label='Print'
|
||||
)
|
||||
q-tooltip Print
|
||||
template(v-if='editorStore.isActive || editorStore.hasPendingChanges')
|
||||
q-btn.acrylic-btn.q-mr-sm(
|
||||
flat
|
||||
icon='las la-times'
|
||||
color='negative'
|
||||
label='Discard'
|
||||
aria-label='Discard'
|
||||
no-caps
|
||||
@click='discardChanges'
|
||||
)
|
||||
q-btn.acrylic-btn(
|
||||
flat
|
||||
icon='las la-check'
|
||||
color='positive'
|
||||
label='Save Changes'
|
||||
aria-label='Save Changes'
|
||||
no-caps
|
||||
@click='saveChanges'
|
||||
)
|
||||
template(v-else)
|
||||
q-btn.acrylic-btn(
|
||||
flat
|
||||
icon='las la-edit'
|
||||
color='deep-orange-9'
|
||||
label='Edit'
|
||||
aria-label='Edit'
|
||||
no-caps
|
||||
@click='editPage'
|
||||
)
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useQuasar } from 'quasar'
|
||||
import { computed, defineAsyncComponent, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { useEditorStore } from 'src/stores/editor'
|
||||
import { useFlagsStore } from 'src/stores/flags'
|
||||
import { usePageStore } from 'src/stores/page'
|
||||
import { useSiteStore } from 'src/stores/site'
|
||||
import { useUserStore } from 'src/stores/user'
|
||||
|
||||
import IconPickerDialog from 'src/components/IconPickerDialog.vue'
|
||||
import SocialSharingMenu from 'src/components/SocialSharingMenu.vue'
|
||||
|
||||
// QUASAR
|
||||
|
||||
const $q = useQuasar()
|
||||
|
||||
// STORES
|
||||
|
||||
const editorStore = useEditorStore()
|
||||
const flagsStore = useFlagsStore()
|
||||
const pageStore = usePageStore()
|
||||
const siteStore = useSiteStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// ROUTER
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
// I18N
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
// COMPUTED
|
||||
|
||||
const editMode = computed(() => {
|
||||
return pageStore.mode === 'edit'
|
||||
})
|
||||
const editCreateMode = computed(() => {
|
||||
return pageStore.mode === 'edit' && pageStore.mode === 'create'
|
||||
})
|
||||
const editUrl = computed(() => {
|
||||
let pagePath = siteStore.useLocales ? `${pageStore.locale}/` : ''
|
||||
pagePath += !pageStore.path ? 'home' : pageStore.path
|
||||
return `/_edit/${pagePath}`
|
||||
})
|
||||
|
||||
// METHODS
|
||||
|
||||
async function discardChanges () {
|
||||
$q.loading.show()
|
||||
try {
|
||||
editorStore.$patch({
|
||||
isActive: false,
|
||||
editor: ''
|
||||
})
|
||||
await pageStore.pageLoad({ id: pageStore.id })
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: 'Page has been reverted to the last saved state.'
|
||||
})
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: 'Failed to reload page state.'
|
||||
})
|
||||
}
|
||||
$q.loading.hide()
|
||||
}
|
||||
|
||||
async function saveChanges () {
|
||||
$q.loading.show()
|
||||
try {
|
||||
await pageStore.pageSave()
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: 'Page saved successfully.'
|
||||
})
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: 'Failed to save page changes.'
|
||||
})
|
||||
}
|
||||
$q.loading.hide()
|
||||
}
|
||||
|
||||
function editPage () {
|
||||
editorStore.$patch({
|
||||
isActive: true,
|
||||
editor: 'markdown'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,33 @@
|
||||
const protanopia = {
|
||||
negative: '#fb8c00',
|
||||
positive: '#2196f3',
|
||||
primary: '#1976D2',
|
||||
secondary: '#2196f3'
|
||||
}
|
||||
|
||||
const deuteranopia = {
|
||||
negative: '#ef6c00',
|
||||
positive: '#2196f3',
|
||||
primary: '#1976D2',
|
||||
secondary: '#2196f3'
|
||||
}
|
||||
|
||||
const tritanopia = {
|
||||
primary: '#e91e63',
|
||||
secondary: '#02C39A'
|
||||
}
|
||||
|
||||
export function getAccessibleColor (name, base, cvd) {
|
||||
switch (cvd) {
|
||||
case 'protanopia': {
|
||||
return protanopia[name] ?? base
|
||||
}
|
||||
case 'deuteranopia': {
|
||||
return deuteranopia[name] ?? base
|
||||
}
|
||||
case 'tritanopia': {
|
||||
return tritanopia[name] ?? base
|
||||
}
|
||||
}
|
||||
return base
|
||||
}
|
||||
@@ -1708,5 +1708,13 @@
|
||||
"admin.editors.markdown.quotesHint": "When typographer is enabled. Double + single quotes replacement pairs. e.g. «»„“ for Russian, „“‚‘ for German, etc.",
|
||||
"admin.editors.saveSuccess": "Editors state saved successfully.",
|
||||
"admin.editors.markdown.saveSuccess": "Markdown editor configuration saved successfully.",
|
||||
"editor.markup.insertTable": "Insert Table"
|
||||
"editor.markup.insertTable": "Insert Table",
|
||||
"editor.markup.header": "Header",
|
||||
"profile.cvdHint": "Alter the color scheme of certain UI elements to account for certain color vision dificiencies.",
|
||||
"profile.cvd": "Color Vision Deficiency",
|
||||
"profile.cvdNone": "None",
|
||||
"profile.cvdProtanopia": "Protanopia",
|
||||
"profile.cvdTritanopia": "Tritanopia",
|
||||
"profile.cvdDeuteranopia": "Deuteranopia",
|
||||
"profile.accessibility": "Accessibility"
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ q-layout(view='hHh Lpr lff')
|
||||
size='md'
|
||||
)
|
||||
main-overlay-dialog
|
||||
footer-nav
|
||||
footer-nav(v-if='!editorStore.isActive')
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
+2
-130
@@ -27,83 +27,7 @@ q-page.column
|
||||
.text-caption.text-accent: strong Unpublished
|
||||
q-separator.q-mx-sm(vertical)
|
||||
.text-caption.text-grey-6 Last modified on #[strong {{lastModified}}]
|
||||
.page-header.row
|
||||
//- PAGE ICON
|
||||
.col-auto.q-pl-md.flex.items-center
|
||||
q-icon.rounded-borders(
|
||||
:name='pageStore.icon'
|
||||
size='64px'
|
||||
color='primary'
|
||||
)
|
||||
//- PAGE HEADER
|
||||
.col.q-pa-md
|
||||
.text-h4.page-header-title {{pageStore.title}}
|
||||
.text-subtitle2.page-header-subtitle {{pageStore.description }}
|
||||
|
||||
//- PAGE ACTIONS
|
||||
.col-auto.q-pa-md.flex.items-center.justify-end
|
||||
q-btn.q-mr-md(
|
||||
flat
|
||||
dense
|
||||
icon='las la-bell'
|
||||
color='grey'
|
||||
aria-label='Watch Page'
|
||||
)
|
||||
q-tooltip Watch Page
|
||||
q-btn.q-mr-md(
|
||||
flat
|
||||
dense
|
||||
icon='las la-bookmark'
|
||||
color='grey'
|
||||
aria-label='Bookmark Page'
|
||||
)
|
||||
q-tooltip Bookmark Page
|
||||
q-btn.q-mr-md(
|
||||
flat
|
||||
dense
|
||||
icon='las la-share-alt'
|
||||
color='grey'
|
||||
aria-label='Share'
|
||||
)
|
||||
q-tooltip Share
|
||||
social-sharing-menu
|
||||
q-btn.q-mr-md(
|
||||
flat
|
||||
dense
|
||||
icon='las la-print'
|
||||
color='grey'
|
||||
aria-label='Print'
|
||||
)
|
||||
q-tooltip Print
|
||||
template(v-if='editorStore.hasPendingChanges')
|
||||
q-btn.acrylic-btn.q-mr-sm(
|
||||
flat
|
||||
icon='las la-times'
|
||||
color='negative'
|
||||
label='Discard'
|
||||
aria-label='Discard'
|
||||
no-caps
|
||||
@click='discardChanges'
|
||||
)
|
||||
q-btn.acrylic-btn(
|
||||
flat
|
||||
icon='las la-check'
|
||||
color='positive'
|
||||
label='Save Changes'
|
||||
aria-label='Save Changes'
|
||||
no-caps
|
||||
@click='saveChanges'
|
||||
)
|
||||
template(v-else)
|
||||
q-btn.acrylic-btn(
|
||||
flat
|
||||
icon='las la-edit'
|
||||
color='deep-orange-9'
|
||||
label='Edit'
|
||||
aria-label='Edit'
|
||||
no-caps
|
||||
@click='editPage'
|
||||
)
|
||||
page-header
|
||||
.page-container.row.no-wrap.items-stretch(style='flex: 1 1 100%;')
|
||||
.col(style='order: 1;')
|
||||
q-no-ssr(
|
||||
@@ -336,8 +260,8 @@ import { useSiteStore } from 'src/stores/site'
|
||||
|
||||
// COMPONENTS
|
||||
|
||||
import SocialSharingMenu from '../components/SocialSharingMenu.vue'
|
||||
import LoadingGeneric from 'src/components/LoadingGeneric.vue'
|
||||
import PageHeader from 'src/components/PageHeader.vue'
|
||||
import PageTags from '../components/PageTags.vue'
|
||||
|
||||
const sideDialogs = {
|
||||
@@ -428,17 +352,6 @@ const relationsCenter = computed(() => {
|
||||
const relationsRight = computed(() => {
|
||||
return pageStore.relations ? pageStore.relations.filter(r => r.position === 'right') : []
|
||||
})
|
||||
const editMode = computed(() => {
|
||||
return pageStore.mode === 'edit'
|
||||
})
|
||||
const editCreateMode = computed(() => {
|
||||
return pageStore.mode === 'edit' && pageStore.mode === 'create'
|
||||
})
|
||||
const editUrl = computed(() => {
|
||||
let pagePath = siteStore.useLocales ? `${pageStore.locale}/` : ''
|
||||
pagePath += !pageStore.path ? 'home' : pageStore.path
|
||||
return `/_edit/${pagePath}`
|
||||
})
|
||||
const lastModified = computed(() => {
|
||||
return pageStore.updatedAt ? DateTime.fromISO(pageStore.updatedAt).toLocaleString(DateTime.DATETIME_MED) : 'N/A'
|
||||
})
|
||||
@@ -545,47 +458,6 @@ function refreshTocExpanded (baseToc, lvl) {
|
||||
return toExpand
|
||||
}
|
||||
}
|
||||
|
||||
async function discardChanges () {
|
||||
$q.loading.show()
|
||||
try {
|
||||
await pageStore.pageLoad({ id: pageStore.id })
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: 'Page has been reverted to the last saved state.'
|
||||
})
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: 'Failed to reload page state.'
|
||||
})
|
||||
}
|
||||
$q.loading.hide()
|
||||
}
|
||||
|
||||
async function saveChanges () {
|
||||
$q.loading.show()
|
||||
try {
|
||||
await pageStore.pageSave()
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: 'Page saved successfully.'
|
||||
})
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: 'Failed to save page changes.'
|
||||
})
|
||||
}
|
||||
$q.loading.hide()
|
||||
}
|
||||
|
||||
function editPage () {
|
||||
editorStore.$patch({
|
||||
isActive: true,
|
||||
editor: 'markdown'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -134,6 +134,21 @@ q-page.q-py-md(:style-fn='pageStyle')
|
||||
toggle-color='primary'
|
||||
:options='appearances'
|
||||
)
|
||||
.text-header.q-mt-lg {{t('profile.accessibility')}}
|
||||
q-item
|
||||
blueprint-icon(icon='visualy-impaired')
|
||||
q-item-section
|
||||
q-item-label {{t(`profile.cvd`)}}
|
||||
q-item-label(caption) {{t(`profile.cvdHint`)}}
|
||||
q-item-section.col-auto
|
||||
q-btn-toggle(
|
||||
v-model='state.config.cvd'
|
||||
push
|
||||
glossy
|
||||
no-caps
|
||||
toggle-color='primary'
|
||||
:options='cvdChoices'
|
||||
)
|
||||
.actions-bar.q-mt-lg
|
||||
q-btn(
|
||||
icon='las la-check'
|
||||
@@ -149,7 +164,7 @@ import gql from 'graphql-tag'
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMeta, useQuasar } from 'quasar'
|
||||
import { onMounted, reactive, watch } from 'vue'
|
||||
import { onMounted, reactive } from 'vue'
|
||||
|
||||
import { useSiteStore } from 'src/stores/site'
|
||||
import { useUserStore } from 'src/stores/user'
|
||||
@@ -185,7 +200,8 @@ const state = reactive({
|
||||
timezone: '',
|
||||
dateFormat: '',
|
||||
timeFormat: '12h',
|
||||
appearance: 'site'
|
||||
appearance: 'site',
|
||||
cvd: 'none'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -206,6 +222,12 @@ const appearances = [
|
||||
{ value: 'light', label: t('profile.appearanceLight') },
|
||||
{ value: 'dark', label: t('profile.appearanceDark') }
|
||||
]
|
||||
const cvdChoices = [
|
||||
{ value: 'none', label: t('profile.cvdNone') },
|
||||
{ value: 'protanopia', label: t('profile.cvdProtanopia') },
|
||||
{ value: 'deuteranopia', label: t('profile.cvdDeuteranopia') },
|
||||
{ value: 'tritanopia', label: t('profile.cvdTritanopia') }
|
||||
]
|
||||
const timezones = Intl.supportedValuesOf('timeZone')
|
||||
|
||||
// METHODS
|
||||
@@ -232,6 +254,7 @@ async function save () {
|
||||
$dateFormat: String
|
||||
$timeFormat: String
|
||||
$appearance: UserSiteAppearance
|
||||
$cvd: UserCvdChoices
|
||||
) {
|
||||
updateProfile (
|
||||
name: $name
|
||||
@@ -242,6 +265,7 @@ async function save () {
|
||||
dateFormat: $dateFormat
|
||||
timeFormat: $timeFormat
|
||||
appearance: $appearance
|
||||
cvd: $cvd
|
||||
) {
|
||||
operation {
|
||||
succeeded
|
||||
@@ -283,5 +307,6 @@ onMounted(() => {
|
||||
state.config.dateFormat = userStore.dateFormat || ''
|
||||
state.config.timeFormat = userStore.timeFormat || '12h'
|
||||
state.config.appearance = userStore.appearance || 'site'
|
||||
state.config.cvd = userStore.cvd || 'none'
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -3,6 +3,7 @@ import jwtDecode from 'jwt-decode'
|
||||
import Cookies from 'js-cookie'
|
||||
import gql from 'graphql-tag'
|
||||
import { DateTime } from 'luxon'
|
||||
import { getAccessibleColor } from 'src/helpers/accessibility'
|
||||
|
||||
export const useUserStore = defineStore('user', {
|
||||
state: () => ({
|
||||
@@ -15,6 +16,7 @@ export const useUserStore = defineStore('user', {
|
||||
dateFormat: 'YYYY-MM-DD',
|
||||
timeFormat: '12h',
|
||||
appearance: 'site',
|
||||
cvd: 'none',
|
||||
permissions: [],
|
||||
iat: 0,
|
||||
exp: null,
|
||||
@@ -87,10 +89,14 @@ export const useUserStore = defineStore('user', {
|
||||
this.dateFormat = resp.prefs.dateFormat || ''
|
||||
this.timeFormat = resp.prefs.timeFormat || '12h'
|
||||
this.appearance = resp.prefs.appearance || 'site'
|
||||
this.cvd = resp.prefs.cvd || 'none'
|
||||
this.profileLoaded = true
|
||||
} catch (err) {
|
||||
console.warn(err)
|
||||
}
|
||||
},
|
||||
getAccessibleColor (base, hexBase) {
|
||||
return getAccessibleColor(base, hexBase, this.cvd)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user