Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix(width): remember full width on remount
After closing and reopening the editor
the full width value was read from initial state again.

Use a singleton instead so the toggled state is persisted.

Signed-off-by: Max <[email protected]>
  • Loading branch information
max-nextcloud committed Aug 12, 2025
commit 9a67122163951b4361d499aa73772c6baa8e4a61
8 changes: 4 additions & 4 deletions src/components/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ import { generateRemoteUrl } from '@nextcloud/router'
import { Awareness } from 'y-protocols/awareness.js'
import { provideConnection } from '../composables/useConnection.ts'
import { useEditorMethods } from '../composables/useEditorMethods.ts'
import { provideEditorWidth } from '../composables/useEditorWidth.ts'
import { provideSaveService } from '../composables/useSaveService.ts'
import { provideSyncService } from '../composables/useSyncService.ts'
import { useSyntaxHighlighting } from '../composables/useSyntaxHighlighting.ts'
Expand Down Expand Up @@ -130,7 +131,6 @@ import MenuBar from './Menu/MenuBar.vue'
import Translate from './Modal/Translate.vue'
import SkeletonLoading from './SkeletonLoading.vue'
import SuggestionsBar from './SuggestionsBar.vue'
import { loadState } from '@nextcloud/initial-state'

export default defineComponent({
name: 'Editor',
Expand Down Expand Up @@ -256,6 +256,9 @@ export default defineComponent({
: createPlainEditor({ language, extensions })
provideEditor(editor)

const { applyEditorWidth } = provideEditorWidth()
applyEditorWidth()

const { setEditable } = useEditorMethods(editor)

const serialize = isRichEditor
Expand Down Expand Up @@ -416,9 +419,6 @@ export default defineComponent({
this.initSession()
this.listenEditorEvents()
}
const initialValue = loadState('text', 'is_full_width_editor', false)
const initialWidth = initialValue ? '100%' : '80ch'
document.documentElement.style.setProperty('--text-editor-max-width', initialWidth)
},
async beforeDestroy() {
if (!this.richWorkspace) {
Expand Down
84 changes: 5 additions & 79 deletions src/components/Editor/WidthToggle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,95 +10,21 @@
</template>

<script setup>
import axios from '@nextcloud/axios'
import { loadState } from '@nextcloud/initial-state'
import { t } from '@nextcloud/l10n'
import { generateUrl } from '@nextcloud/router'
import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
import { computed, nextTick, ref, watch } from 'vue'
import { nextTick, watch } from 'vue'
import { useEditor } from '../../composables/useEditor.ts'
import { useEditorWidth } from '../../composables/useEditorWidth.ts'

const { editor } = useEditor()
const isFullWidth = ref(loadState('text', 'is_full_width_editor', false))
watch(isFullWidth, (checked) => {
axios.post(generateUrl('/apps/text/settings'), {
key: 'is_full_width_editor',
value: checked ? '1' : '0',
})
})
const { isFullWidth } = useEditorWidth()

const width = computed(() => (isFullWidth.value ? '100%' : '80ch'))
const updateEditorWidth = (newWidth) => {
document.documentElement.style.setProperty('--text-editor-max-width', newWidth)
const redrawEditor = () => {
nextTick(() => {
const { commands, view } = editor
view.updateState(view.state)
commands.focus()
})
}
watch(width, updateEditorWidth)
updateEditorWidth(width)
</script>

<script>
watch(isFullWidth, redrawEditor)
</script>

<style scoped lang="scss">
.session-list {
height: var(--default-clickable-area);
}

.avatar-list {
width: min-content !important;
padding-inline: var(--default-grid-baseline);

:deep(.button-vue__icon) {
display: inline-flex;
flex-direction: row-reverse;
width: min-content;

.avatar-wrapper {
margin: 3px -12px 3px 0;
z-index: 1;
overflow: hidden;
}
}
}

.session-menu {
max-width: 280px;
padding-top: 6px;
padding-bottom: 6px;

ul li {
align-items: center;
display: flex;
padding: 6px;

.avatar-wrapper {
height: 36px;
width: 36px;
margin-right: 6px;
}

.session-label {
padding-right: 3px;
}

.guest-label {
padding-left: 3px;
color: var(--color-text-maxcontrast);
}
}
}

label {
display: block;
margin: 8px;
}

.hint {
margin: 8px;
color: var(--color-text-maxcontrast);
}
</style>
58 changes: 58 additions & 0 deletions src/composables/useEditorWidth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

/*
* Handle the state of the full editor width toggle.
*
* Apply it by setting the css variable on the document.
* Keep it around after the editor is destroyed for the next mount.
* Persist it in the user settings.
*
*/

import axios from '@nextcloud/axios'
import { loadState } from '@nextcloud/initial-state'
import { generateUrl } from '@nextcloud/router'
import {
computed,
inject,
provide,
ref,
watch,
type InjectionKey,
type Ref,
} from 'vue'

// Keep the current value around when leaving the editor and reopening
let valueSingleton = loadState('text', 'is_full_width_editor', false)

export const editorWidthKey = Symbol('text:editor:width') as InjectionKey<
Ref<boolean>
>
export const provideEditorWidth = () => {
const isFullWidth = ref(valueSingleton)
provide(editorWidthKey, isFullWidth)
watch(isFullWidth, (checked) => {
valueSingleton = checked
axios.post(generateUrl('/apps/text/settings'), {
key: 'is_full_width_editor',
value: checked ? '1' : '0',
})
})
const width = computed(() => (isFullWidth.value ? '100%' : '80ch'))
const applyEditorWidth = () => {
document.documentElement.style.setProperty(
'--text-editor-max-width',
width.value,
)
}
watch(width, applyEditorWidth)
return { applyEditorWidth }
}

export const useEditorWidth = () => {
const isFullWidth = inject(editorWidthKey) as Ref<boolean>
return { isFullWidth }
}