Skip to content

Commit

Permalink
Attach picker to control on desktop, inlay on mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
danon committed Dec 5, 2023
1 parent 5012235 commit 8538d8a
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 137 deletions.
77 changes: 48 additions & 29 deletions resources/js/components/forms/emoji-picker.vue
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
<template>
<div class="emoji-picker">
<div class="card card-body">
<div class="panel">
<input class="form-control" placeholder="Wyszukaj emoji..." v-model="searchPhrase"/>
</div>

<div class="scroll" @mouseleave="mouseLeave">
<div class="category" v-for="category in emojis.categories">
<h5>{{ category.name }}</h5>
<template v-for="name in category.subcategories">
<img
v-for="code in emojis.subcategories[name]"
v-show="visible(emojis.emoticons[code])"
class="emoji"
:src="url(emojis.emoticons[code])"
:title="emojis.emoticons[code].name"
:alt="emojis.emoticons[code].native"
@mouseover="mouseOver(emojis.emoticons[code])"/>
</template>
</div>
</div>
<div style="display:flex; flex-direction:column;">
<div class="emoji-grid">
<div class="emoji-scroll" @mouseleave="mouseLeave">
<div class="category" v-for="category in emojis.categories">
<h5>{{ category.name }}</h5>
<div class="category-emojis">
<template v-for="name in category.subcategories">
<img
v-for="code in emojis.subcategories[name]"
v-show="visible(emojis.emoticons[code])"
class="emoji"
:src="url(emojis.emoticons[code])"
:title="emojis.emoticons[code].name"
:alt="emojis.emoticons[code].native"
@mouseover="mouseOver(emojis.emoticons[code])"/>
</template>
</div>
</div>
</div>

<div class="panel">
<div class="footer">
<div v-show="emoji">
<div class="emoji-details">
<p class="name">{{ emoji && emoji.name }}</p>
<code class="id">:{{ emoji && emoji.id }}:</code>
<div class="emoji-preview-box">
<div v-show="emoji" class="emoji-preview">
<div class="emoji-name">
<p class="title">{{ emoji && emoji.name }}</p>
<code class="id">:{{ emoji && emoji.id }}:</code>
</div>
<small>{{ keywords(emoji) }}</small>
</div>
<small>{{ keywords(emoji) }}</small>
<p v-show="!emoji" class="emoji-placeholder">
Wybierz emoji
</p>
</div>
<p v-show="!emoji" class="placeholder">Wybierz emoji</p>
</div>

<div class="search-box">
<input class="form-control" v-model="searchPhrase" placeholder="Wyszukaj emoji..."/>
<button class="btn btn-primary" type="button">
<i class="fas fa-times"/>
Zamknij
</button>
</div>
</div>
</div>
Expand All @@ -56,11 +66,11 @@ export default {
return `:${emoji.id}:, ${emoji.name}`;
},
visible(emoji) {
if (emoji.id.includes(this.searchPhrase)) {
if (containsWords(emoji.id, this.searchSlug)) {
return true;
}
for (const keyword of emoji.keywords) {
if (keyword.includes(this.searchPhrase)) {
if (containsWords(keyword, this.searchSlug)) {
return true;
}
}
Expand All @@ -78,6 +88,15 @@ export default {
mouseLeave() {
this.emoji = null;
}
},
computed: {
searchSlug() {
return this.searchPhrase.replaceAll(/[^a-z0-9]/gi, '');
}
}
};
function containsWords(subject, searchPhrase) {
return subject.replaceAll(/[-_]/g, '').includes(searchPhrase);
}
</script>
77 changes: 46 additions & 31 deletions resources/js/components/forms/markdown.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
<template>
<div :class="{'is-invalid': isInvalid}" class="editor" style="position:relative">
<div style="position:absolute; right:5px;">
<vue-emoji-picker :emojis="emojis"/>
</div>
<div :class="{'is-invalid': isInvalid}" class="editor">
<vue-tabs @click="switchTab" :items="tabs" :current-tab="tabs.indexOf(currentTab)" type="pills" class="mb-2">
<div v-if="isContent" class="btn-toolbar ml-auto">
<div class="btn-group d-inline mr-2 ml-2 mt-1" role="group" aria-label="...">
Expand All @@ -13,64 +10,73 @@
class="btn btn-sm btn-control"
:title="button.can ? button.title : button.break"
:style="{opacity: button.can ? '1.0' : '0.4', cursor: button.can ? 'pointer' : 'default'}">
<i :class="['fas fa-fw', button.icon]"></i>
<i :class="['fas fa-fw', button.icon]"/>
</button>
</div>
</div>
</vue-tabs>

<div v-show="isContent">
<div :class="['form-control', {'is-invalid': error !== null}]"
style="height:inherit; outline:none; box-shadow:none; border:none; padding-left:0; padding-right:0;">
<vue-editor
ref="editor"
v-model="valueLocal"
placeholder="Kliknij, aby dodać treść..."
:autocompleteSource="autocomplete"
v-paste:success="addAsset"
@submit="save"
@cancel="cancel"
@state="updateState"/>
<div style="position:relative">
<div v-show="isContent">
<div :class="['form-control', {'is-invalid': error !== null}]"
style="height:inherit; outline:none; box-shadow:none; border:none; padding-left:0; padding-right:0;">
<vue-editor
ref="editor"
v-model="valueLocal"
placeholder="Kliknij, aby dodać treść..."
:autocompleteSource="autocomplete"
v-paste:success="addAsset"
@submit="save"
@cancel="cancel"
@state="updateState"/>
</div>
<vue-error :message="error"/>
</div>
<vue-error :message="error"></vue-error>
</div>

<div v-show="isPreview" v-html="previewHtml" class="preview post-content"></div>
<div v-show="isPreview" v-html="previewHtml" class="preview post-content"/>

<hr class="m-0">
<div class="emoji-picker-container">
<div class="triangle"/>
<vue-emoji-picker :emojis="emojis"/>
</div>
</div>

<slot name="bottom"></slot>
<hr class="m-0"/>
<slot name="bottom"/>

<div class="row no-gutters pt-1 pl-2 pr-2">
<div class="small mr-auto">
<template v-if="isProcessing">
<i class="fas fa-spinner fa-spin small"></i>

<i class="fas fa-spinner fa-spin small"/>
<span class="small">{{ progress }}%</span>
</template>

<a v-else :aria-label="uploadTooltip" tabindex="-1" data-balloon-length="large" data-balloon-pos="up-left"
data-balloon-nofocus href="javascript:" class="small text-muted" @click="chooseFile">
<i class="far fa-image"></i>

<i class="far fa-image"/>
<span class="d-none d-sm-inline">Kliknij, aby dodać załącznik lub wklej ze schowka.</span>
</a>

<slot name="options"></slot>
<slot name="options"/>
</div>

<div class="small ml-auto">
<a href="#js-wiki-help" tabindex="-1" data-bs-toggle="collapse" class="small text-muted">
<i class="fa fab fa-markdown"/>
<i class="fab fa-markdown"/>
Instrukcja obsługi Markdown
</a>
</div>
</div>

<div v-if="assets.length" class="row pt-3 pb-3 pl-2 pr-2">
<div v-for="item in assets" :key="item.id" class="col-sm-2">
<vue-thumbnail :url="item.url" @delete="deleteAsset(item)" @insert="insertAssetAtCaret(item)"
:aria-label="item.name" data-balloon-pos="down" name="asset"></vue-thumbnail>
<vue-thumbnail
name="asset"
data-balloon-pos="down"
:url="item.url"
:aria-label="item.name"
@delete="deleteAsset(item)"
@insert="insertAssetAtCaret(item)"/>
</div>
</div>

Expand All @@ -80,7 +86,7 @@
</div>
</div>

<slot></slot>
<slot/>
</div>
</template>

Expand Down Expand Up @@ -225,6 +231,14 @@ export default class VueMarkdown extends Vue {
break: null,
icon: 'fa-indent'
},
insertEmoji: {
click: () => {
},
can: false,
title: 'Dodaj emotikonę',
break: 'Dodanie tutaj emotikony mogłoby spowodować uszkodzenie składni',
icon: 'fa-smile-beam',
}
};
@Ref('editor')
Expand Down Expand Up @@ -312,6 +326,7 @@ export default class VueMarkdown extends Vue {
this.buttons.key.can = state.canKey;
this.buttons.indentMore.can = state.canIndent;
this.buttons.indentLess.can = state.canIndent;
this.buttons.insertEmoji.can = true;
}
autocomplete(nick: string) {
Expand Down
Loading

0 comments on commit 8538d8a

Please sign in to comment.