mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-04-15 17:24:11 +00:00
Added md editor ui dropdown options & their back-end storage
Still need to perform actual in-editor functionality for those controls.
This commit is contained in:
parent
3995b01399
commit
9fd5190c70
6 changed files with 59 additions and 1 deletions
app
resources
routes
|
@ -29,6 +29,8 @@ return [
|
||||||
'ui-shortcuts' => '{}',
|
'ui-shortcuts' => '{}',
|
||||||
'ui-shortcuts-enabled' => false,
|
'ui-shortcuts-enabled' => false,
|
||||||
'dark-mode-enabled' => env('APP_DEFAULT_DARK_MODE', false),
|
'dark-mode-enabled' => env('APP_DEFAULT_DARK_MODE', false),
|
||||||
|
'md-show-preview' => true,
|
||||||
|
'md-scroll-sync' => true,
|
||||||
'bookshelves_view_type' => env('APP_VIEWS_BOOKSHELVES', 'grid'),
|
'bookshelves_view_type' => env('APP_VIEWS_BOOKSHELVES', 'grid'),
|
||||||
'bookshelf_view_type' => env('APP_VIEWS_BOOKSHELF', 'grid'),
|
'bookshelf_view_type' => env('APP_VIEWS_BOOKSHELF', 'grid'),
|
||||||
'books_view_type' => env('APP_VIEWS_BOOKS', 'grid'),
|
'books_view_type' => env('APP_VIEWS_BOOKS', 'grid'),
|
||||||
|
|
|
@ -115,6 +115,9 @@ class UserPreferencesController extends Controller
|
||||||
return response('', 204);
|
return response('', 204);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the favorite status for a code language.
|
||||||
|
*/
|
||||||
public function updateCodeLanguageFavourite(Request $request)
|
public function updateCodeLanguageFavourite(Request $request)
|
||||||
{
|
{
|
||||||
$validated = $this->validate($request, [
|
$validated = $this->validate($request, [
|
||||||
|
@ -134,5 +137,27 @@ class UserPreferencesController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
setting()->putForCurrentUser('code-language-favourites', implode(',', $currentFavorites));
|
setting()->putForCurrentUser('code-language-favourites', implode(',', $currentFavorites));
|
||||||
|
return response('', 204);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a boolean user preference setting.
|
||||||
|
*/
|
||||||
|
public function updateBooleanPreference(Request $request)
|
||||||
|
{
|
||||||
|
$allowedKeys = ['md-scroll-sync', 'md-show-preview'];
|
||||||
|
$validated = $this->validate($request, [
|
||||||
|
'name' => ['required', 'string'],
|
||||||
|
'value' => ['required'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!in_array($validated['name'], $allowedKeys)) {
|
||||||
|
return response('Invalid boolean preference', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = $validated['value'] === 'true' ? 'true' : 'false';
|
||||||
|
setting()->putForCurrentUser($validated['name'], $value);
|
||||||
|
|
||||||
|
return response('', 204);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ export class MarkdownEditor extends Component {
|
||||||
|
|
||||||
this.display = this.$refs.display;
|
this.display = this.$refs.display;
|
||||||
this.input = this.$refs.input;
|
this.input = this.$refs.input;
|
||||||
|
this.settingContainer = this.$refs.settingContainer;
|
||||||
|
|
||||||
this.editor = null;
|
this.editor = null;
|
||||||
initEditor({
|
initEditor({
|
||||||
|
@ -74,6 +75,15 @@ export class MarkdownEditor extends Component {
|
||||||
toolbarLabel.closest('.markdown-editor-wrap').classList.add('active');
|
toolbarLabel.closest('.markdown-editor-wrap').classList.add('active');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Setting changes
|
||||||
|
this.settingContainer.addEventListener('change', e => {
|
||||||
|
const actualInput = e.target.parentNode.querySelector('input[type="hidden"]');
|
||||||
|
const name = actualInput.getAttribute('name');
|
||||||
|
const value = actualInput.getAttribute('value');
|
||||||
|
window.$http.patch('/preferences/update-boolean', {name, value});
|
||||||
|
// TODO - Update state locally
|
||||||
|
});
|
||||||
|
|
||||||
// Refresh CodeMirror on container resize
|
// Refresh CodeMirror on container resize
|
||||||
const resizeDebounced = debounce(() => this.editor.cm.refresh(), 100, false);
|
const resizeDebounced = debounce(() => this.editor.cm.refresh(), 100, false);
|
||||||
const observer = new ResizeObserver(resizeDebounced);
|
const observer = new ResizeObserver(resizeDebounced);
|
||||||
|
|
|
@ -157,6 +157,16 @@ html.markdown-editor-display.dark-mode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.editor-toolbar .buttons {
|
||||||
|
font-size: $fs-m;
|
||||||
|
.dropdown-menu {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.toggle-switch {
|
||||||
|
margin: $-s 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.editor-toolbar .buttons button {
|
.editor-toolbar .buttons button {
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
width: 2rem;
|
width: 2rem;
|
||||||
|
|
|
@ -10,13 +10,23 @@
|
||||||
<div class="editor-toolbar-label text-mono px-m py-xs flex-container-row items-center flex">
|
<div class="editor-toolbar-label text-mono px-m py-xs flex-container-row items-center flex">
|
||||||
<span>{{ trans('entities.pages_md_editor') }}</span>
|
<span>{{ trans('entities.pages_md_editor') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons flex-container-row items-stretch">
|
<div component="dropdown" class="buttons flex-container-row items-stretch">
|
||||||
@if(config('services.drawio'))
|
@if(config('services.drawio'))
|
||||||
<button class="text-button" type="button" data-action="insertDrawing" title="{{ trans('entities.pages_md_insert_drawing') }}">@icon('drawing')</button>
|
<button class="text-button" type="button" data-action="insertDrawing" title="{{ trans('entities.pages_md_insert_drawing') }}">@icon('drawing')</button>
|
||||||
@endif
|
@endif
|
||||||
<button class="text-button" type="button" data-action="insertImage" title="{{ trans('entities.pages_md_insert_image') }}">@icon('image')</button>
|
<button class="text-button" type="button" data-action="insertImage" title="{{ trans('entities.pages_md_insert_image') }}">@icon('image')</button>
|
||||||
<button class="text-button" type="button" data-action="insertLink" title="{{ trans('entities.pages_md_insert_link') }}">@icon('link')</button>
|
<button class="text-button" type="button" data-action="insertLink" title="{{ trans('entities.pages_md_insert_link') }}">@icon('link')</button>
|
||||||
<button class="text-button" type="button" data-action="fullscreen" title="{{ trans('common.fullscreen') }}">@icon('fullscreen')</button>
|
<button class="text-button" type="button" data-action="fullscreen" title="{{ trans('common.fullscreen') }}">@icon('fullscreen')</button>
|
||||||
|
<button refs="dropdown@toggle" class="text-button" type="button" title="{{ trans('common.more') }}">@icon('more')</button>
|
||||||
|
<div refs="dropdown@menu markdown-editor@setting-container" class="dropdown-menu" role="menu">
|
||||||
|
<div class="px-m">
|
||||||
|
@include('form.toggle-switch', ['name' => 'md-show-preview', 'label' => 'Show preview', 'value' => setting()->getForCurrentUser('md-show-preview')])
|
||||||
|
</div>
|
||||||
|
<hr class="m-none">
|
||||||
|
<div class="px-m">
|
||||||
|
@include('form.toggle-switch', ['name' => 'md-scroll-sync', 'label' => 'Sync preview scroll', 'value' => setting()->getForCurrentUser('md-scroll-sync')])
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -254,6 +254,7 @@ Route::middleware('auth')->group(function () {
|
||||||
Route::patch('/preferences/change-expansion/{type}', [UserPreferencesController::class, 'changeExpansion']);
|
Route::patch('/preferences/change-expansion/{type}', [UserPreferencesController::class, 'changeExpansion']);
|
||||||
Route::patch('/preferences/toggle-dark-mode', [UserPreferencesController::class, 'toggleDarkMode']);
|
Route::patch('/preferences/toggle-dark-mode', [UserPreferencesController::class, 'toggleDarkMode']);
|
||||||
Route::patch('/preferences/update-code-language-favourite', [UserPreferencesController::class, 'updateCodeLanguageFavourite']);
|
Route::patch('/preferences/update-code-language-favourite', [UserPreferencesController::class, 'updateCodeLanguageFavourite']);
|
||||||
|
Route::patch('/preferences/update-boolean', [UserPreferencesController::class, 'updateBooleanPreference']);
|
||||||
|
|
||||||
// User API Tokens
|
// User API Tokens
|
||||||
Route::get('/settings/users/{userId}/create-api-token', [UserApiTokenController::class, 'create']);
|
Route::get('/settings/users/{userId}/create-api-token', [UserApiTokenController::class, 'create']);
|
||||||
|
|
Loading…
Add table
Reference in a new issue