Added core code-lang-favourites JS, PHP & CSS logic

- Got the functionality now working to favourite items and store that
  status within the system for the user.
- Improved CSS display for usability.
This commit is contained in:
Dan Brown 2022-07-25 13:10:27 +01:00
parent ebc5a53410
commit 0df5ae0658
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
5 changed files with 76 additions and 8 deletions

View File

@ -289,6 +289,27 @@ class UserController extends Controller
return response('', 204); return response('', 204);
} }
public function updateCodeLanguageFavourite(Request $request)
{
$validated = $this->validate($request, [
'language' => ['required', 'string', 'max:20'],
'active' => ['required', 'bool'],
]);
$currentFavoritesStr = setting()->getForCurrentUser('code-language-favourites', '');
$currentFavorites = array_filter(explode(',', $currentFavoritesStr));
$isFav = in_array($validated['language'], $currentFavorites);
if (!$isFav && $validated['active']) {
$currentFavorites[] = $validated['language'];
} else if ($isFav && !$validated['active']) {
$index = array_search($validated['language'], $currentFavorites);
array_splice($currentFavorites, $index, 1);
}
setting()->putUser(user(), 'code-language-favourites', implode(',', $currentFavorites));
}
/** /**
* Changed the stored preference for a list sort order. * Changed the stored preference for a list sort order.
*/ */

View File

@ -15,12 +15,14 @@ class CodeEditor {
this.languageInput = this.$refs.languageInput; this.languageInput = this.$refs.languageInput;
this.historyDropDown = this.$refs.historyDropDown; this.historyDropDown = this.$refs.historyDropDown;
this.historyList = this.$refs.historyList; this.historyList = this.$refs.historyList;
this.favourites = new Set(this.$opts.favourites.split(','));
this.callback = null; this.callback = null;
this.editor = null; this.editor = null;
this.history = {}; this.history = {};
this.historyKey = 'code_history'; this.historyKey = 'code_history';
this.setupListeners(); this.setupListeners();
this.setupFavourites();
} }
setupListeners() { setupListeners() {
@ -49,6 +51,43 @@ class CodeEditor {
}); });
} }
setupFavourites() {
for (const button of this.languageLinks) {
this.setupFavouritesForButton(button);
}
this.sortLanguageList();
}
/**
* @param {HTMLButtonElement} button
*/
setupFavouritesForButton(button) {
const language = button.dataset.lang;
let isFavorite = this.favourites.has(language);
button.setAttribute('data-favourite', isFavorite ? 'true' : 'false');
onChildEvent(button.parentElement, '.lang-option-favorite-toggle', 'click', () => {
isFavorite = !isFavorite;
isFavorite ? this.favourites.add(language) : this.favourites.delete(language);
button.setAttribute('data-favourite', isFavorite ? 'true' : 'false');
window.$http.patch('/settings/users/update-code-language-favourite', {
language: language,
active: isFavorite
});
this.sortLanguageList();
if (isFavorite) {
button.scrollIntoView({block: "center", behavior: "smooth"});
}
});
}
sortLanguageList() {
// TODO
}
save() { save() {
if (this.callback) { if (this.callback) {
this.callback(this.editor.getValue(), this.languageInput.value); this.callback(this.editor.getValue(), this.languageInput.value);

View File

@ -666,7 +666,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
text-align: left; text-align: left;
font-family: $mono; font-family: $mono;
font-size: 0.7rem; font-size: 0.7rem;
padding-right: 24px + $-m; padding-left: 24px + $-s;
&:hover, &.active { &:hover, &.active {
background-color: var(--color-primary-light); background-color: var(--color-primary-light);
color: var(--color-primary); color: var(--color-primary);
@ -675,7 +675,8 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
.code-editor button.lang-option-favorite-toggle { .code-editor button.lang-option-favorite-toggle {
position: absolute; position: absolute;
right: 0; top: 0;
left: 0;
width: 28px; width: 28px;
font-size: 1rem; font-size: 1rem;
border: 0; border: 0;
@ -684,11 +685,17 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
z-index: 2; z-index: 2;
height: 100%; height: 100%;
text-align: center; text-align: center;
color: var(--color-primary);
svg { svg {
margin: 0; margin: 0;
} }
} }
.code-editor button[data-favourite="true"] ~ .action-favourite,
.code-editor button[data-favourite="false"] ~ .action-unfavourite {
display: none;
}
.code-editor label { .code-editor label {
background-color: var(--color-primary-light); background-color: var(--color-primary-light);
width: 100%; width: 100%;

View File

@ -1,5 +1,7 @@
<div> <div>
<div components="popup code-editor" class="popup-background code-editor"> <div components="popup code-editor"
option:code-editor:favourites="{{ setting()->getForCurrentUser('code-language-favourites', '') }}"
class="popup-background code-editor">
<div refs="code-editor@container" class="popup-body" tabindex="-1"> <div refs="code-editor@container" class="popup-body" tabindex="-1">
<div class="popup-header flex-container-row primary-background"> <div class="popup-header flex-container-row primary-background">
@ -30,11 +32,9 @@
@foreach($languages as $language) @foreach($languages as $language)
<div class="relative"> <div class="relative">
<button type="button" refs="code-editor@languageLink" data-lang="{{ strtolower($language) }}">{{ $language }}</button> <button type="button" refs="code-editor@languageLink" data-favourite="false" data-lang="{{ strtolower($language) }}">{{ $language }}</button>
<button class="lang-option-favorite-toggle" title="{{ trans('common.favourite') }}" data-alt-title="{{ trans('common.unfavourite') }}"> <button class="lang-option-favorite-toggle action-favourite" data-title="{{ trans('common.favourite') }}">@icon('star-outline')</button>
<div class="pre-favorite">@icon('star-outline')</div> <button class="lang-option-favorite-toggle action-unfavourite" data-title="{{ trans('common.unfavourite') }}">@icon('star')</button>
<div class="post-favorite" style="display: none;">@icon('star')</div>
</button>
</div> </div>
@endforeach @endforeach
</div> </div>

View File

@ -235,6 +235,7 @@ Route::middleware('auth')->group(function () {
Route::patch('/settings/users/{id}/change-sort/{type}', [UserController::class, 'changeSort']); Route::patch('/settings/users/{id}/change-sort/{type}', [UserController::class, 'changeSort']);
Route::patch('/settings/users/{id}/update-expansion-preference/{key}', [UserController::class, 'updateExpansionPreference']); Route::patch('/settings/users/{id}/update-expansion-preference/{key}', [UserController::class, 'updateExpansionPreference']);
Route::patch('/settings/users/toggle-dark-mode', [UserController::class, 'toggleDarkMode']); Route::patch('/settings/users/toggle-dark-mode', [UserController::class, 'toggleDarkMode']);
Route::patch('/settings/users/update-code-language-favourite', [UserController::class, 'updateCodeLanguageFavourite']);
Route::post('/settings/users/create', [UserController::class, 'store']); Route::post('/settings/users/create', [UserController::class, 'store']);
Route::get('/settings/users/{id}', [UserController::class, 'edit']); Route::get('/settings/users/{id}', [UserController::class, 'edit']);
Route::put('/settings/users/{id}', [UserController::class, 'update']); Route::put('/settings/users/{id}', [UserController::class, 'update']);