vue-intergrall-plugins 1.1.90 → 1.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +220 -220
  2. package/dist/dist/vue-intergrall-plugins.css +1 -1
  3. package/dist/vue-intergrall-plugins.esm.js +223 -89
  4. package/dist/vue-intergrall-plugins.min.js +11 -11
  5. package/dist/vue-intergrall-plugins.ssr.js +276 -147
  6. package/package.json +1 -1
  7. package/src/lib-components/Buttons/IconButton.vue +27 -27
  8. package/src/lib-components/Buttons/SimpleButton.vue +140 -140
  9. package/src/lib-components/Cards/Card.vue +490 -490
  10. package/src/lib-components/Cards/CardCheck.vue +35 -35
  11. package/src/lib-components/Cards/CardFile.vue +163 -163
  12. package/src/lib-components/Chat/BtnDownloadAllFiles.vue +36 -36
  13. package/src/lib-components/Chat/BtnEmojis.vue +118 -118
  14. package/src/lib-components/Chat/BtnExpand.vue +17 -17
  15. package/src/lib-components/Chat/BtnFiles.vue +486 -486
  16. package/src/lib-components/Chat/BtnMic.vue +60 -60
  17. package/src/lib-components/Chat/BtnScreenShare.vue +31 -31
  18. package/src/lib-components/Chat/BtnStandardMessages.vue +17 -17
  19. package/src/lib-components/Chat/ExpandTextarea.vue +427 -427
  20. package/src/lib-components/Chat/MultipleFilePreview.vue +291 -291
  21. package/src/lib-components/Chat/Picker.vue +525 -525
  22. package/src/lib-components/Chat/RemainingCharacters.vue +28 -28
  23. package/src/lib-components/Chat/SingleFilePreview.vue +94 -94
  24. package/src/lib-components/Chat/SkeletonPicker.vue +110 -110
  25. package/src/lib-components/Chat/StandardMessages.vue +252 -252
  26. package/src/lib-components/Chat/TextFooter.vue +1007 -1007
  27. package/src/lib-components/Email/EmailExpanded.vue +270 -270
  28. package/src/lib-components/Email/EmailFile.vue +192 -192
  29. package/src/lib-components/Email/EmailFrom.vue +66 -66
  30. package/src/lib-components/Email/EmailItem.vue +867 -850
  31. package/src/lib-components/Email/EmailTo.vue +64 -64
  32. package/src/lib-components/Loader/Loader.vue +78 -78
  33. package/src/lib-components/Messages/AnexoMensagem.vue +625 -497
  34. package/src/lib-components/Messages/CardAttachment.vue +61 -61
  35. package/src/lib-components/Messages/CardMessages.vue +687 -687
  36. package/src/lib-components/Messages/ChatMessages.vue +259 -78
  37. package/src/lib-components/Messages/InteratividadeBotoes.vue +197 -197
  38. package/src/lib-components/Messages/InteratividadeContato.vue +32 -32
  39. package/src/lib-components/Messages/InteratividadeContatoItem.vue +235 -235
  40. package/src/lib-components/Messages/InteratividadeFormulario.vue +334 -334
  41. package/src/lib-components/Messages/InteratividadePopup.vue +95 -95
  42. package/src/lib-components/Messages/LinkPreview.vue +176 -176
  43. package/src/lib-components/Scroll/ScrollContent.vue +166 -166
  44. package/src/lib-components/Templates/TemplateGenerator.vue +640 -640
  45. package/src/lib-components/Templates/TemplateMessage.vue +83 -83
  46. package/src/lib-components/Templates/TemplateSingle.vue +478 -478
@@ -1,525 +1,525 @@
1
- <template>
2
- <div :class="`ck-reset_all-excluded sm-emoji-picker box-shadow ${!fullView ? 'small' : ''}`" @click.stop>
3
- <SkeletonPicker v-if="loading" />
4
- <div class="sm-emoji-header" v-show="fullView">
5
- <span
6
- class="sm-emoji-link"
7
- v-for="(category, indexCategoryHeader) in allEmojis.categories"
8
- :key="`ich-${indexCategoryHeader}`"
9
- :title="category.name"
10
- :class="{ active: categoriaSelecionada == category.id }"
11
- @click="pickerHeaderHandler($event, category.id)"
12
- v-html="`<span>${category.svg}</span>`"
13
- ></span>
14
- </div>
15
- <div class="sm-emoji-scroll" ref="sm-scroll">
16
- <div class="sm-emoji-search" ref="sm-search" v-show="fullView">
17
- <input type="text" name="emoji-search" @input="onSearchInput" v-model="search" />
18
- </div>
19
- <template v-if="!filteredList.length && fullView">
20
- <div
21
- v-for="(category, indexCategory) in allEmojis.categories"
22
- :key="`ic-${indexCategory}`"
23
- >
24
- <div class="sm-emoji-selection">
25
- <span
26
- class="sm-emoji-title"
27
- :id="category.id"
28
- v-html="`${category.svg} ${category.name}`"
29
- :title="category.name"
30
- ></span>
31
- <div class="sm-emoji-group">
32
- <div
33
- class="sm-emoji-item"
34
- v-for="(emojiKey, key) in category.emojis"
35
- :key="`ee-${key}-${category.id}`"
36
- >
37
- <span
38
- v-if="
39
- allEmojis.emojis &&
40
- allEmojis.emojis[emojiKey] &&
41
- allEmojis.emojis[emojiKey].finalEmoji
42
- "
43
- @click="addEmoji(allEmojis.emojis[emojiKey], emojiKey)"
44
- >
45
- {{ allEmojis.emojis[emojiKey].finalEmoji }}
46
- </span>
47
- </div>
48
- </div>
49
- </div>
50
- </div>
51
- </template>
52
- <template v-else-if="filteredList.length && fullView">
53
- <div class="sm-emoji-group">
54
- <div
55
- class="sm-emoji-item"
56
- v-for="(emoji, key) in filteredList"
57
- :key="`ees-${key}`"
58
- >
59
- <span @click="addEmoji(emoji)"> {{ emoji.finalEmoji }} </span>
60
- </div>
61
- </div>
62
- </template>
63
- <template v-else-if="!fullView">
64
- <div class="sm-emoji-group small">
65
- <div
66
- class="sm-emoji-item"
67
- v-for="(emojiKey, key) in recentEmojis"
68
- :key="`eer-${key}`"
69
- >
70
- <span
71
- v-if="
72
- allEmojis.emojis &&
73
- allEmojis.emojis[emojiKey] &&
74
- allEmojis.emojis[emojiKey].finalEmoji
75
- "
76
- @click="addEmoji(allEmojis.emojis[emojiKey], emojiKey)"
77
- >
78
- {{ allEmojis.emojis[emojiKey].finalEmoji }}
79
- </span>
80
- </div>
81
- <button class="sm-emoji-item add-more" @click="openFullPicker">
82
- +
83
- </button>
84
- </div>
85
- </template>
86
- </div>
87
- </div>
88
- </template>
89
-
90
- <script>
91
- import allEmojis from "../../services/emojis/all.json";
92
- import SkeletonPicker from "./SkeletonPicker";
93
-
94
- export default {
95
- components: { SkeletonPicker },
96
- props: {
97
- hasLoading: {
98
- type: Boolean,
99
- default: true,
100
- },
101
- recentViewOnly: {
102
- type: Boolean,
103
- default: false,
104
- }
105
- },
106
- computed: {
107
- recentEmojis() {
108
- try {
109
- const recent = allEmojis.categories.find(cat => cat.id === 'recent');
110
- const people = allEmojis.categories.find(cat => cat.id === 'people');
111
-
112
- if(!recent && !people) throw new Error("Categorias 'recent' e 'people' não encontradas");
113
-
114
- if(!recent.emojis && !people.emojis) throw new Error("Nenhum emoji encontrado nas categorias 'recent' e 'people'");
115
-
116
- const sliceLimit = 7
117
-
118
- if(!recent.emojis.length) return people.emojis.slice(0, sliceLimit);
119
-
120
- if(recent.emojis.length < sliceLimit) {
121
- const missing = sliceLimit - recent.emojis.length;
122
- return [...recent.emojis, ...people.emojis.slice(0, missing)];
123
- }
124
-
125
- return recent.emojis.slice(0, sliceLimit);
126
- } catch (e) {
127
- console.error("Erro ao obter os emojis recentes", e);
128
- return [];
129
- }
130
- },
131
- fullView() {
132
- return this.forceFullPicker || !this.recentViewOnly;
133
- },
134
- },
135
- data() {
136
- return {
137
- allEmojis: {},
138
- categoriaSelecionada: "",
139
- search: "",
140
- filteredList: [],
141
- loading: true,
142
- isSticky: false,
143
- forceFullPicker: false,
144
- searchTimer: null
145
- };
146
- },
147
- mounted() {
148
- this.allEmojis = allEmojis;
149
- this.loadEmojis();
150
- },
151
- methods: {
152
- onSearchInput() {
153
- clearTimeout(this.searchTimer);
154
- this.searchTimer = setTimeout(() => this.filterEmojis(), 180);
155
- },
156
- openFullPicker() {
157
- this.forceFullPicker = true;
158
- },
159
- emojiHeaders() {
160
- try {
161
- const emojis = {
162
- recent: {
163
- name: "Recentes",
164
- svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M13 4h-2l-.001 7H9v2h2v2h2v-2h4v-2h-4z"></path><path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10"></path></svg>`,
165
- },
166
- people: {
167
- name: "Pessoas & Expressoes",
168
- svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10"></path><path d="M8 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 8 7M16 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 16 7M15.232 15c-.693 1.195-1.87 2-3.349 2-1.477 0-2.655-.805-3.347-2H15m3-2H6a6 6 0 1 0 12 0"></path></svg>`,
169
- },
170
- nature: {
171
- name: "Animais & Natureza",
172
- svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M15.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 15.5 8M8.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 8.5 8"></path><path d="M18.933 0h-.027c-.97 0-2.138.787-3.018 1.497-1.274-.374-2.612-.51-3.887-.51-1.285 0-2.616.133-3.874.517C7.245.79 6.069 0 5.093 0h-.027C3.352 0 .07 2.67.002 7.026c-.039 2.479.276 4.238 1.04 5.013.254.258.882.677 1.295.882.191 3.177.922 5.238 2.536 6.38.897.637 2.187.949 3.2 1.102C8.04 20.6 8 20.795 8 21c0 1.773 2.35 3 4 3 1.648 0 4-1.227 4-3 0-.201-.038-.393-.072-.586 2.573-.385 5.435-1.877 5.925-7.587.396-.22.887-.568 1.104-.788.763-.774 1.079-2.534 1.04-5.013C23.929 2.67 20.646 0 18.933 0M3.223 9.135c-.237.281-.837 1.155-.884 1.238-.15-.41-.368-1.349-.337-3.291.051-3.281 2.478-4.972 3.091-5.031.256.015.731.27 1.265.646-1.11 1.171-2.275 2.915-2.352 5.125-.133.546-.398.858-.783 1.313M12 22c-.901 0-1.954-.693-2-1 0-.654.475-1.236 1-1.602V20a1 1 0 1 0 2 0v-.602c.524.365 1 .947 1 1.602-.046.307-1.099 1-2 1m3-3.48v.02a4.752 4.752 0 0 0-1.262-1.02c1.092-.516 2.239-1.334 2.239-2.217 0-1.842-1.781-2.195-3.977-2.195-2.196 0-3.978.354-3.978 2.195 0 .883 1.148 1.701 2.238 2.217A4.8 4.8 0 0 0 9 18.539v-.025c-1-.076-2.182-.281-2.973-.842-1.301-.92-1.838-3.045-1.853-6.478l.023-.041c.496-.826 1.49-1.45 1.804-3.102 0-2.047 1.357-3.631 2.362-4.522C9.37 3.178 10.555 3 11.948 3c1.447 0 2.685.192 3.733.57 1 .9 2.316 2.465 2.316 4.48.313 1.651 1.307 2.275 1.803 3.102.035.058.068.117.102.178-.059 5.967-1.949 7.01-4.902 7.19m6.628-8.202c-.037-.065-.074-.13-.113-.195a7.587 7.587 0 0 0-.739-.987c-.385-.455-.648-.768-.782-1.313-.076-2.209-1.241-3.954-2.353-5.124.531-.376 1.004-.63 1.261-.647.636.071 3.044 1.764 3.096 5.031.027 1.81-.347 3.218-.37 3.235"></path></svg>`,
173
- },
174
- foods: {
175
- name: "Comidas & Bebibas",
176
- svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M17 4.978c-1.838 0-2.876.396-3.68.934.513-1.172 1.768-2.934 4.68-2.934a1 1 0 0 0 0-2c-2.921 0-4.629 1.365-5.547 2.512-.064.078-.119.162-.18.244C11.73 1.838 10.798.023 9.207.023 8.579.022 7.85.306 7 .978 5.027 2.54 5.329 3.902 6.492 4.999 3.609 5.222 0 7.352 0 12.969c0 4.582 4.961 11.009 9 11.009 1.975 0 2.371-.486 3-1 .629.514 1.025 1 3 1 4.039 0 9-6.418 9-11 0-5.953-4.055-8-7-8M8.242 2.546c.641-.508.943-.523.965-.523.426.169.975 1.405 1.357 3.055-1.527-.629-2.741-1.352-2.98-1.846.059-.112.241-.356.658-.686M15 21.978c-1.08 0-1.21-.109-1.559-.402l-.176-.146c-.367-.302-.816-.452-1.266-.452s-.898.15-1.266.452l-.176.146c-.347.292-.477.402-1.557.402-2.813 0-7-5.389-7-9.009 0-5.823 4.488-5.991 5-5.991 1.939 0 2.484.471 3.387 1.251l.323.276a1.995 1.995 0 0 0 2.58 0l.323-.276c.902-.78 1.447-1.251 3.387-1.251.512 0 5 .168 5 6 0 3.617-4.187 9-7 9"></path></svg>`,
177
- },
178
- activity: {
179
- name: "Atividades",
180
- svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 0C5.373 0 0 5.372 0 12c0 6.627 5.373 12 12 12 6.628 0 12-5.373 12-12 0-6.628-5.372-12-12-12m9.949 11H17.05c.224-2.527 1.232-4.773 1.968-6.113A9.966 9.966 0 0 1 21.949 11M13 11V2.051a9.945 9.945 0 0 1 4.432 1.564c-.858 1.491-2.156 4.22-2.392 7.385H13zm-2 0H8.961c-.238-3.165-1.536-5.894-2.393-7.385A9.95 9.95 0 0 1 11 2.051V11zm0 2v8.949a9.937 9.937 0 0 1-4.432-1.564c.857-1.492 2.155-4.221 2.393-7.385H11zm4.04 0c.236 3.164 1.534 5.893 2.392 7.385A9.92 9.92 0 0 1 13 21.949V13h2.04zM4.982 4.887C5.718 6.227 6.726 8.473 6.951 11h-4.9a9.977 9.977 0 0 1 2.931-6.113M2.051 13h4.9c-.226 2.527-1.233 4.771-1.969 6.113A9.972 9.972 0 0 1 2.051 13m16.967 6.113c-.735-1.342-1.744-3.586-1.968-6.113h4.899a9.961 9.961 0 0 1-2.931 6.113"></path></svg>`,
181
- },
182
- places: {
183
- name: "Viagens & Lugares",
184
- svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M6.5 12C5.122 12 4 13.121 4 14.5S5.122 17 6.5 17 9 15.879 9 14.5 7.878 12 6.5 12m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5M17.5 12c-1.378 0-2.5 1.121-2.5 2.5s1.122 2.5 2.5 2.5 2.5-1.121 2.5-2.5-1.122-2.5-2.5-2.5m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5"></path><path d="M22.482 9.494l-1.039-.346L21.4 9h.6c.552 0 1-.439 1-.992 0-.006-.003-.008-.003-.008H23c0-1-.889-2-1.984-2h-.642l-.731-1.717C19.262 3.012 18.091 2 16.764 2H7.236C5.909 2 4.738 3.012 4.357 4.283L3.626 6h-.642C1.889 6 1 7 1 8h.003S1 8.002 1 8.008C1 8.561 1.448 9 2 9h.6l-.043.148-1.039.346a2.001 2.001 0 0 0-1.359 2.097l.751 7.508a1 1 0 0 0 .994.901H3v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h6v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h1.096a.999.999 0 0 0 .994-.901l.751-7.508a2.001 2.001 0 0 0-1.359-2.097M6.273 4.857C6.402 4.43 6.788 4 7.236 4h9.527c.448 0 .834.43.963.857L19.313 9H4.688l1.585-4.143zM7 21H5v-1h2v1zm12 0h-2v-1h2v1zm2.189-3H2.811l-.662-6.607L3 11h18l.852.393L21.189 18z"></path></svg>`,
185
- },
186
- objects: {
187
- name: "Objetos",
188
- svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 0a9 9 0 0 0-5 16.482V21s2.035 3 5 3 5-3 5-3v-4.518A9 9 0 0 0 12 0zm0 2c3.86 0 7 3.141 7 7s-3.14 7-7 7-7-3.141-7-7 3.14-7 7-7zM9 17.477c.94.332 1.946.523 3 .523s2.06-.19 3-.523v.834c-.91.436-1.925.689-3 .689a6.924 6.924 0 0 1-3-.69v-.833zm.236 3.07A8.854 8.854 0 0 0 12 21c.965 0 1.888-.167 2.758-.451C14.155 21.173 13.153 22 12 22c-1.102 0-2.117-.789-2.764-1.453z"></path><path d="M14.745 12.449h-.004c-.852-.024-1.188-.858-1.577-1.824-.421-1.061-.703-1.561-1.182-1.566h-.009c-.481 0-.783.497-1.235 1.537-.436.982-.801 1.811-1.636 1.791l-.276-.043c-.565-.171-.853-.691-1.284-1.794-.125-.313-.202-.632-.27-.913-.051-.213-.127-.53-.195-.634C7.067 9.004 7.039 9 6.99 9A1 1 0 0 1 7 7h.01c1.662.017 2.015 1.373 2.198 2.134.486-.981 1.304-2.058 2.797-2.075 1.531.018 2.28 1.153 2.731 2.141l.002-.008C14.944 8.424 15.327 7 16.979 7h.032A1 1 0 1 1 17 9h-.011c-.149.076-.256.474-.319.709a6.484 6.484 0 0 1-.311.951c-.429.973-.79 1.789-1.614 1.789"></path></svg>`,
189
- },
190
- symbols: {
191
- name: "Simbolos",
192
- svg: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z"></path></svg>`,
193
- },
194
- flags: {
195
- name: "Bandeiras",
196
- svg: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path><line x1="4" y1="22" x2="4" y2="15"></line></svg>`,
197
- },
198
- };
199
-
200
- if (this.allEmojis.categories[0].id != "recent")
201
- this.allEmojis.categories.unshift({
202
- emojis: this.getRecentEmojis(),
203
- id: "recent",
204
- name: "",
205
- });
206
- this.allEmojis.categories = this.allEmojis.categories.filter((cat) => {
207
- const { id } = cat;
208
- if (emojis[id]) {
209
- cat.name = emojis[id].name;
210
- cat.svg = emojis[id].svg;
211
- return cat;
212
- }
213
- });
214
- } catch (e) {
215
- console.error("Erro ao gerar os emojis headers");
216
- console.error(e);
217
- }
218
- },
219
- processEmojisInChunks() {
220
- try {
221
- const keys = Object.keys(this.allEmojis.emojis || {});
222
- const chunkSize = 150;
223
- let i = 0;
224
- const process = () => {
225
- const end = Math.min(i + chunkSize, keys.length);
226
- for (let j = i; j < end; j++) {
227
- const key = keys[j];
228
- const keyCode = this.allEmojis.emojis[key];
229
- if (!keyCode || keyCode.hasOwnProperty("finalEmoji")) continue;
230
- const { b } = keyCode;
231
- const hexPoints = b.split(/\s|-/);
232
- const codePoints = hexPoints.map((hex) => parseInt(hex, 16));
233
- const finalEmoji = String.fromCodePoint.apply(null, codePoints);
234
- this.$set(this.allEmojis.emojis[key], "hexa", hexPoints.join(""));
235
- this.$set(this.allEmojis.emojis[key], "finalEmoji", finalEmoji);
236
- }
237
- i = end;
238
- if (i < keys.length) {
239
- if (window.requestIdleCallback) requestIdleCallback(process);
240
- else setTimeout(process, 0);
241
- }
242
- };
243
- if (window.requestIdleCallback) requestIdleCallback(process);
244
- else setTimeout(process, 0);
245
- } catch (e) {
246
- console.error("Erro ao gerar os emojis em chunks", e);
247
- }
248
- },
249
- loadEmojis() {
250
- try {
251
- if(!this.hasLoading) {
252
- this.loading = false;
253
- return
254
- }
255
- this.emojiHeaders();
256
- this.processEmojisInChunks();
257
- this.loading = false;
258
- } catch (e) {
259
- console.error("Erro ao carregar os emojis");
260
- console.error(e);
261
- }
262
- },
263
- getRecentEmojis() {
264
- const recentEmojis = localStorage.getItem("recent-emojis");
265
- if (recentEmojis) return recentEmojis.split(",");
266
- return [];
267
- },
268
- setEmojiOnLocalStorage(emojiKey) {
269
- try {
270
- let finalStr = "";
271
- const recentEmojis = localStorage.getItem("recent-emojis");
272
- if (recentEmojis) {
273
- const arrRecent = recentEmojis.split(",");
274
- if (!arrRecent.includes(emojiKey)) {
275
- if (arrRecent.length < 20) {
276
- finalStr = `${emojiKey},${recentEmojis}`;
277
- } else {
278
- arrRecent.pop();
279
- finalStr = `${emojiKey},${arrRecent.join(",")}`;
280
- }
281
- }
282
- } else {
283
- finalStr = `${emojiKey}`;
284
- }
285
- if (finalStr) {
286
- localStorage.setItem("recent-emojis", finalStr);
287
- const finalArr = finalStr.split(",").filter((str) => {
288
- return str ? str : false;
289
- });
290
- this.allEmojis.categories[0].emojis = finalArr;
291
- }
292
- } catch (e) {
293
- console.error("Erro ao setar o emoji no localStorage");
294
- console.error(e);
295
- }
296
- },
297
- addEmoji(emoji, emojiKey) {
298
- this.setEmojiOnLocalStorage(emojiKey);
299
- this.$emit("insert-emoji", emoji);
300
- },
301
- pickerHeaderHandler(e, id) {
302
- try {
303
- const container = this.$refs["sm-scroll"];
304
- const target = this.$el.querySelector(`#${id}`);
305
- if (!container || !target) {
306
- this.categoriaSelecionada = id;
307
- return;
308
- }
309
- const containerRect = container.getBoundingClientRect();
310
- const targetRect = target.getBoundingClientRect();
311
- const offset = targetRect.top - containerRect.top + container.scrollTop;
312
- container.scrollTo({ top: offset, behavior: "smooth" });
313
- this.categoriaSelecionada = id;
314
- } catch (e) {
315
- console.error("Erro ao mudar de categoria", e);
316
- }
317
- },
318
- filterEmojis() {
319
- if (!this.search.trim()) return (this.filteredList = []);
320
-
321
- const rawList = [];
322
- for (let key in this.allEmojis.emojis) {
323
- const emoji = this.allEmojis.emojis[key];
324
- const { a } = emoji;
325
- const search = this.search.toUpperCase();
326
- const upperA = a.toUpperCase();
327
- if (upperA.indexOf(search) >= 0) rawList.push(emoji);
328
- }
329
- this.filteredList = rawList;
330
- },
331
- },
332
- };
333
- </script>
334
-
335
- <style>
336
- .box-shadow {
337
- -webkit-box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2),
338
- 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
339
- -moz-box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2),
340
- 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
341
- box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14),
342
- 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
343
- }
344
-
345
- .sm-emoji-picker {
346
- width: 306px;
347
- height: 250px;
348
- z-index: 2;
349
- border: 1px solid #ccc;
350
- border-radius: 5px;
351
- background-color: #fff;
352
- display: flex;
353
- flex-direction: column;
354
- }
355
-
356
- .sm-emoji-picker.small {
357
- height: 40px!important;
358
- }
359
-
360
- .sm-emoji-picker.small .sm-emoji-scroll {
361
- height: 100%;
362
- max-height: 100%;
363
- overflow: hidden;
364
- }
365
- .sm-emoji-picker.small .sm-emoji-scroll .sm-emoji-group.small {
366
- justify-content: center;
367
- align-items: center;
368
- flex-wrap: nowrap;
369
- }
370
-
371
- .add-more {
372
- --size: 26px;
373
- background: #f0f0f0;
374
- border: 1px solid #ccc;
375
- border-radius: 50%;
376
- width: var(--size);
377
- min-width: var(--size);
378
- height: var(--size);
379
- min-height: var(--size);
380
- display: flex;
381
- justify-content: center;
382
- align-items: center;
383
- font-size: 16px;
384
- font-weight: bold;
385
- }
386
-
387
- .sm-emoji-header {
388
- width: 100%;
389
- display: flex;
390
- align-items: center;
391
- justify-content: space-between;
392
- margin: 10px 0;
393
- border-bottom: 1px solid #ccc;
394
- }
395
-
396
- .sm-emoji-link {
397
- padding: 0 5px 5px 5px;
398
- display: flex;
399
- justify-content: center;
400
- align-items: center;
401
- cursor: pointer;
402
- opacity: 0.9;
403
- transition: all 200ms;
404
- border-bottom: 2px solid transparent;
405
- }
406
- .sm-emoji-link > span svg {
407
- margin: 0;
408
- padding: 0;
409
- fill: #999;
410
- }
411
- /* force no-fill for stroke-based icons and the last two header svgs */
412
- .sm-emoji-link > span svg[stroke],
413
- .sm-emoji-header .sm-emoji-link:nth-last-child(-n+2) > span svg {
414
- fill: none !important;
415
- }
416
-
417
- /* hover/active: filled icons get fill; stroke icons keep no fill and change stroke color */
418
- .sm-emoji-link:hover > span svg:not([stroke]),
419
- .sm-emoji-link.active > span svg:not([stroke]) {
420
- opacity: 1;
421
- fill: #666;
422
- }
423
-
424
- .sm-emoji-link:hover > span svg[stroke],
425
- .sm-emoji-link.active > span svg[stroke] {
426
- opacity: 1;
427
- fill: none !important;
428
- stroke: #666;
429
- }
430
-
431
- .sm-emoji-scroll {
432
- width: 100%;
433
- height: calc(100% - 52px);
434
- max-height: calc(100% - 52px);
435
- scroll-behavior: smooth;
436
- overflow-y: auto;
437
- overflow-x: hidden;
438
- scrollbar-color: #888 rgba(0, 0, 0, 0.2);
439
- scrollbar-width: 8px;
440
- position: relative;
441
- }
442
- .sm-emoji-scroll::-webkit-scrollbar {
443
- width: 8px;
444
- }
445
-
446
- .sm-emoji-scroll::-webkit-scrollbar-track {
447
- background-color: rgba(0, 0, 0, 0.2);
448
- }
449
-
450
- .sm-emoji-scroll::-webkit-scrollbar-thumb {
451
- transition-duration: 0.5s;
452
- background-color: #666;
453
- }
454
-
455
- .sm-emoji-scroll::-webkit-scrollbar-thumb:hover {
456
- background-color: #555;
457
- }
458
-
459
- .sm-emoji-search {
460
- width: 100%;
461
- display: flex;
462
- align-items: center;
463
- justify-content: center;
464
- position: sticky;
465
- top: 0;
466
- z-index: 1;
467
- background: #fff;
468
- padding-bottom: 10px;
469
- }
470
- .sm-emoji-search > input {
471
- width: 90%;
472
- outline: none;
473
- border: 1px solid #ccc;
474
- border-radius: 2.5px;
475
- padding: 5px 10px;
476
- transition: border 200ms;
477
- }
478
- .sm-emoji-search > input:focus,
479
- .sm-emoji-search > input:active,
480
- .sm-emoji-search > input:hover {
481
- outline: none;
482
- border: 1px solid #999;
483
- }
484
- .sm-emoji-search.sticky {
485
- position: fixed;
486
- width: 310px;
487
- background-color: #fff;
488
- }
489
-
490
- .sm-emoji-selection {
491
- width: 100%;
492
- margin-bottom: 10px;
493
- }
494
- .sm-emoji-title {
495
- width: 100%;
496
- display: flex;
497
- justify-content: flex-start;
498
- align-items: center;
499
- background-color: #f7f7f7;
500
- padding: 5px 0;
501
- white-space: nowrap;
502
- text-overflow: ellipsis;
503
- overflow: hidden;
504
- }
505
- .sm-emoji-title svg {
506
- margin: 0 5px;
507
- }
508
-
509
- .sm-emoji-group {
510
- width: 100%;
511
- display: flex;
512
- flex-wrap: wrap;
513
- font-size: 22px;
514
- }
515
-
516
- .sm-emoji-item {
517
- cursor: pointer;
518
- opacity: 0.8;
519
- transition: opacity 200ms;
520
- margin: 3.5px;
521
- }
522
- .sm-emoji-item:hover {
523
- opacity: 1;
524
- }
525
- </style>
1
+ <template>
2
+ <div :class="`ck-reset_all-excluded sm-emoji-picker box-shadow ${!fullView ? 'small' : ''}`" @click.stop>
3
+ <SkeletonPicker v-if="loading" />
4
+ <div class="sm-emoji-header" v-show="fullView">
5
+ <span
6
+ class="sm-emoji-link"
7
+ v-for="(category, indexCategoryHeader) in allEmojis.categories"
8
+ :key="`ich-${indexCategoryHeader}`"
9
+ :title="category.name"
10
+ :class="{ active: categoriaSelecionada == category.id }"
11
+ @click="pickerHeaderHandler($event, category.id)"
12
+ v-html="`<span>${category.svg}</span>`"
13
+ ></span>
14
+ </div>
15
+ <div class="sm-emoji-scroll" ref="sm-scroll">
16
+ <div class="sm-emoji-search" ref="sm-search" v-show="fullView">
17
+ <input type="text" name="emoji-search" @input="onSearchInput" v-model="search" />
18
+ </div>
19
+ <template v-if="!filteredList.length && fullView">
20
+ <div
21
+ v-for="(category, indexCategory) in allEmojis.categories"
22
+ :key="`ic-${indexCategory}`"
23
+ >
24
+ <div class="sm-emoji-selection">
25
+ <span
26
+ class="sm-emoji-title"
27
+ :id="category.id"
28
+ v-html="`${category.svg} ${category.name}`"
29
+ :title="category.name"
30
+ ></span>
31
+ <div class="sm-emoji-group">
32
+ <div
33
+ class="sm-emoji-item"
34
+ v-for="(emojiKey, key) in category.emojis"
35
+ :key="`ee-${key}-${category.id}`"
36
+ >
37
+ <span
38
+ v-if="
39
+ allEmojis.emojis &&
40
+ allEmojis.emojis[emojiKey] &&
41
+ allEmojis.emojis[emojiKey].finalEmoji
42
+ "
43
+ @click="addEmoji(allEmojis.emojis[emojiKey], emojiKey)"
44
+ >
45
+ {{ allEmojis.emojis[emojiKey].finalEmoji }}
46
+ </span>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ </template>
52
+ <template v-else-if="filteredList.length && fullView">
53
+ <div class="sm-emoji-group">
54
+ <div
55
+ class="sm-emoji-item"
56
+ v-for="(emoji, key) in filteredList"
57
+ :key="`ees-${key}`"
58
+ >
59
+ <span @click="addEmoji(emoji)"> {{ emoji.finalEmoji }} </span>
60
+ </div>
61
+ </div>
62
+ </template>
63
+ <template v-else-if="!fullView">
64
+ <div class="sm-emoji-group small">
65
+ <div
66
+ class="sm-emoji-item"
67
+ v-for="(emojiKey, key) in recentEmojis"
68
+ :key="`eer-${key}`"
69
+ >
70
+ <span
71
+ v-if="
72
+ allEmojis.emojis &&
73
+ allEmojis.emojis[emojiKey] &&
74
+ allEmojis.emojis[emojiKey].finalEmoji
75
+ "
76
+ @click="addEmoji(allEmojis.emojis[emojiKey], emojiKey)"
77
+ >
78
+ {{ allEmojis.emojis[emojiKey].finalEmoji }}
79
+ </span>
80
+ </div>
81
+ <button class="sm-emoji-item add-more" @click="openFullPicker">
82
+ +
83
+ </button>
84
+ </div>
85
+ </template>
86
+ </div>
87
+ </div>
88
+ </template>
89
+
90
+ <script>
91
+ import allEmojis from "../../services/emojis/all.json";
92
+ import SkeletonPicker from "./SkeletonPicker";
93
+
94
+ export default {
95
+ components: { SkeletonPicker },
96
+ props: {
97
+ hasLoading: {
98
+ type: Boolean,
99
+ default: true,
100
+ },
101
+ recentViewOnly: {
102
+ type: Boolean,
103
+ default: false,
104
+ }
105
+ },
106
+ computed: {
107
+ recentEmojis() {
108
+ try {
109
+ const recent = allEmojis.categories.find(cat => cat.id === 'recent');
110
+ const people = allEmojis.categories.find(cat => cat.id === 'people');
111
+
112
+ if(!recent && !people) throw new Error("Categorias 'recent' e 'people' não encontradas");
113
+
114
+ if(!recent.emojis && !people.emojis) throw new Error("Nenhum emoji encontrado nas categorias 'recent' e 'people'");
115
+
116
+ const sliceLimit = 7
117
+
118
+ if(!recent.emojis.length) return people.emojis.slice(0, sliceLimit);
119
+
120
+ if(recent.emojis.length < sliceLimit) {
121
+ const missing = sliceLimit - recent.emojis.length;
122
+ return [...recent.emojis, ...people.emojis.slice(0, missing)];
123
+ }
124
+
125
+ return recent.emojis.slice(0, sliceLimit);
126
+ } catch (e) {
127
+ console.error("Erro ao obter os emojis recentes", e);
128
+ return [];
129
+ }
130
+ },
131
+ fullView() {
132
+ return this.forceFullPicker || !this.recentViewOnly;
133
+ },
134
+ },
135
+ data() {
136
+ return {
137
+ allEmojis: {},
138
+ categoriaSelecionada: "",
139
+ search: "",
140
+ filteredList: [],
141
+ loading: true,
142
+ isSticky: false,
143
+ forceFullPicker: false,
144
+ searchTimer: null
145
+ };
146
+ },
147
+ mounted() {
148
+ this.allEmojis = allEmojis;
149
+ this.loadEmojis();
150
+ },
151
+ methods: {
152
+ onSearchInput() {
153
+ clearTimeout(this.searchTimer);
154
+ this.searchTimer = setTimeout(() => this.filterEmojis(), 180);
155
+ },
156
+ openFullPicker() {
157
+ this.forceFullPicker = true;
158
+ },
159
+ emojiHeaders() {
160
+ try {
161
+ const emojis = {
162
+ recent: {
163
+ name: "Recentes",
164
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M13 4h-2l-.001 7H9v2h2v2h2v-2h4v-2h-4z"></path><path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10"></path></svg>`,
165
+ },
166
+ people: {
167
+ name: "Pessoas & Expressoes",
168
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10"></path><path d="M8 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 8 7M16 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 16 7M15.232 15c-.693 1.195-1.87 2-3.349 2-1.477 0-2.655-.805-3.347-2H15m3-2H6a6 6 0 1 0 12 0"></path></svg>`,
169
+ },
170
+ nature: {
171
+ name: "Animais & Natureza",
172
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M15.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 15.5 8M8.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 8.5 8"></path><path d="M18.933 0h-.027c-.97 0-2.138.787-3.018 1.497-1.274-.374-2.612-.51-3.887-.51-1.285 0-2.616.133-3.874.517C7.245.79 6.069 0 5.093 0h-.027C3.352 0 .07 2.67.002 7.026c-.039 2.479.276 4.238 1.04 5.013.254.258.882.677 1.295.882.191 3.177.922 5.238 2.536 6.38.897.637 2.187.949 3.2 1.102C8.04 20.6 8 20.795 8 21c0 1.773 2.35 3 4 3 1.648 0 4-1.227 4-3 0-.201-.038-.393-.072-.586 2.573-.385 5.435-1.877 5.925-7.587.396-.22.887-.568 1.104-.788.763-.774 1.079-2.534 1.04-5.013C23.929 2.67 20.646 0 18.933 0M3.223 9.135c-.237.281-.837 1.155-.884 1.238-.15-.41-.368-1.349-.337-3.291.051-3.281 2.478-4.972 3.091-5.031.256.015.731.27 1.265.646-1.11 1.171-2.275 2.915-2.352 5.125-.133.546-.398.858-.783 1.313M12 22c-.901 0-1.954-.693-2-1 0-.654.475-1.236 1-1.602V20a1 1 0 1 0 2 0v-.602c.524.365 1 .947 1 1.602-.046.307-1.099 1-2 1m3-3.48v.02a4.752 4.752 0 0 0-1.262-1.02c1.092-.516 2.239-1.334 2.239-2.217 0-1.842-1.781-2.195-3.977-2.195-2.196 0-3.978.354-3.978 2.195 0 .883 1.148 1.701 2.238 2.217A4.8 4.8 0 0 0 9 18.539v-.025c-1-.076-2.182-.281-2.973-.842-1.301-.92-1.838-3.045-1.853-6.478l.023-.041c.496-.826 1.49-1.45 1.804-3.102 0-2.047 1.357-3.631 2.362-4.522C9.37 3.178 10.555 3 11.948 3c1.447 0 2.685.192 3.733.57 1 .9 2.316 2.465 2.316 4.48.313 1.651 1.307 2.275 1.803 3.102.035.058.068.117.102.178-.059 5.967-1.949 7.01-4.902 7.19m6.628-8.202c-.037-.065-.074-.13-.113-.195a7.587 7.587 0 0 0-.739-.987c-.385-.455-.648-.768-.782-1.313-.076-2.209-1.241-3.954-2.353-5.124.531-.376 1.004-.63 1.261-.647.636.071 3.044 1.764 3.096 5.031.027 1.81-.347 3.218-.37 3.235"></path></svg>`,
173
+ },
174
+ foods: {
175
+ name: "Comidas & Bebibas",
176
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M17 4.978c-1.838 0-2.876.396-3.68.934.513-1.172 1.768-2.934 4.68-2.934a1 1 0 0 0 0-2c-2.921 0-4.629 1.365-5.547 2.512-.064.078-.119.162-.18.244C11.73 1.838 10.798.023 9.207.023 8.579.022 7.85.306 7 .978 5.027 2.54 5.329 3.902 6.492 4.999 3.609 5.222 0 7.352 0 12.969c0 4.582 4.961 11.009 9 11.009 1.975 0 2.371-.486 3-1 .629.514 1.025 1 3 1 4.039 0 9-6.418 9-11 0-5.953-4.055-8-7-8M8.242 2.546c.641-.508.943-.523.965-.523.426.169.975 1.405 1.357 3.055-1.527-.629-2.741-1.352-2.98-1.846.059-.112.241-.356.658-.686M15 21.978c-1.08 0-1.21-.109-1.559-.402l-.176-.146c-.367-.302-.816-.452-1.266-.452s-.898.15-1.266.452l-.176.146c-.347.292-.477.402-1.557.402-2.813 0-7-5.389-7-9.009 0-5.823 4.488-5.991 5-5.991 1.939 0 2.484.471 3.387 1.251l.323.276a1.995 1.995 0 0 0 2.58 0l.323-.276c.902-.78 1.447-1.251 3.387-1.251.512 0 5 .168 5 6 0 3.617-4.187 9-7 9"></path></svg>`,
177
+ },
178
+ activity: {
179
+ name: "Atividades",
180
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 0C5.373 0 0 5.372 0 12c0 6.627 5.373 12 12 12 6.628 0 12-5.373 12-12 0-6.628-5.372-12-12-12m9.949 11H17.05c.224-2.527 1.232-4.773 1.968-6.113A9.966 9.966 0 0 1 21.949 11M13 11V2.051a9.945 9.945 0 0 1 4.432 1.564c-.858 1.491-2.156 4.22-2.392 7.385H13zm-2 0H8.961c-.238-3.165-1.536-5.894-2.393-7.385A9.95 9.95 0 0 1 11 2.051V11zm0 2v8.949a9.937 9.937 0 0 1-4.432-1.564c.857-1.492 2.155-4.221 2.393-7.385H11zm4.04 0c.236 3.164 1.534 5.893 2.392 7.385A9.92 9.92 0 0 1 13 21.949V13h2.04zM4.982 4.887C5.718 6.227 6.726 8.473 6.951 11h-4.9a9.977 9.977 0 0 1 2.931-6.113M2.051 13h4.9c-.226 2.527-1.233 4.771-1.969 6.113A9.972 9.972 0 0 1 2.051 13m16.967 6.113c-.735-1.342-1.744-3.586-1.968-6.113h4.899a9.961 9.961 0 0 1-2.931 6.113"></path></svg>`,
181
+ },
182
+ places: {
183
+ name: "Viagens & Lugares",
184
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M6.5 12C5.122 12 4 13.121 4 14.5S5.122 17 6.5 17 9 15.879 9 14.5 7.878 12 6.5 12m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5M17.5 12c-1.378 0-2.5 1.121-2.5 2.5s1.122 2.5 2.5 2.5 2.5-1.121 2.5-2.5-1.122-2.5-2.5-2.5m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5"></path><path d="M22.482 9.494l-1.039-.346L21.4 9h.6c.552 0 1-.439 1-.992 0-.006-.003-.008-.003-.008H23c0-1-.889-2-1.984-2h-.642l-.731-1.717C19.262 3.012 18.091 2 16.764 2H7.236C5.909 2 4.738 3.012 4.357 4.283L3.626 6h-.642C1.889 6 1 7 1 8h.003S1 8.002 1 8.008C1 8.561 1.448 9 2 9h.6l-.043.148-1.039.346a2.001 2.001 0 0 0-1.359 2.097l.751 7.508a1 1 0 0 0 .994.901H3v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h6v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h1.096a.999.999 0 0 0 .994-.901l.751-7.508a2.001 2.001 0 0 0-1.359-2.097M6.273 4.857C6.402 4.43 6.788 4 7.236 4h9.527c.448 0 .834.43.963.857L19.313 9H4.688l1.585-4.143zM7 21H5v-1h2v1zm12 0h-2v-1h2v1zm2.189-3H2.811l-.662-6.607L3 11h18l.852.393L21.189 18z"></path></svg>`,
185
+ },
186
+ objects: {
187
+ name: "Objetos",
188
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 0a9 9 0 0 0-5 16.482V21s2.035 3 5 3 5-3 5-3v-4.518A9 9 0 0 0 12 0zm0 2c3.86 0 7 3.141 7 7s-3.14 7-7 7-7-3.141-7-7 3.14-7 7-7zM9 17.477c.94.332 1.946.523 3 .523s2.06-.19 3-.523v.834c-.91.436-1.925.689-3 .689a6.924 6.924 0 0 1-3-.69v-.833zm.236 3.07A8.854 8.854 0 0 0 12 21c.965 0 1.888-.167 2.758-.451C14.155 21.173 13.153 22 12 22c-1.102 0-2.117-.789-2.764-1.453z"></path><path d="M14.745 12.449h-.004c-.852-.024-1.188-.858-1.577-1.824-.421-1.061-.703-1.561-1.182-1.566h-.009c-.481 0-.783.497-1.235 1.537-.436.982-.801 1.811-1.636 1.791l-.276-.043c-.565-.171-.853-.691-1.284-1.794-.125-.313-.202-.632-.27-.913-.051-.213-.127-.53-.195-.634C7.067 9.004 7.039 9 6.99 9A1 1 0 0 1 7 7h.01c1.662.017 2.015 1.373 2.198 2.134.486-.981 1.304-2.058 2.797-2.075 1.531.018 2.28 1.153 2.731 2.141l.002-.008C14.944 8.424 15.327 7 16.979 7h.032A1 1 0 1 1 17 9h-.011c-.149.076-.256.474-.319.709a6.484 6.484 0 0 1-.311.951c-.429.973-.79 1.789-1.614 1.789"></path></svg>`,
189
+ },
190
+ symbols: {
191
+ name: "Simbolos",
192
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z"></path></svg>`,
193
+ },
194
+ flags: {
195
+ name: "Bandeiras",
196
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path><line x1="4" y1="22" x2="4" y2="15"></line></svg>`,
197
+ },
198
+ };
199
+
200
+ if (this.allEmojis.categories[0].id != "recent")
201
+ this.allEmojis.categories.unshift({
202
+ emojis: this.getRecentEmojis(),
203
+ id: "recent",
204
+ name: "",
205
+ });
206
+ this.allEmojis.categories = this.allEmojis.categories.filter((cat) => {
207
+ const { id } = cat;
208
+ if (emojis[id]) {
209
+ cat.name = emojis[id].name;
210
+ cat.svg = emojis[id].svg;
211
+ return cat;
212
+ }
213
+ });
214
+ } catch (e) {
215
+ console.error("Erro ao gerar os emojis headers");
216
+ console.error(e);
217
+ }
218
+ },
219
+ processEmojisInChunks() {
220
+ try {
221
+ const keys = Object.keys(this.allEmojis.emojis || {});
222
+ const chunkSize = 150;
223
+ let i = 0;
224
+ const process = () => {
225
+ const end = Math.min(i + chunkSize, keys.length);
226
+ for (let j = i; j < end; j++) {
227
+ const key = keys[j];
228
+ const keyCode = this.allEmojis.emojis[key];
229
+ if (!keyCode || keyCode.hasOwnProperty("finalEmoji")) continue;
230
+ const { b } = keyCode;
231
+ const hexPoints = b.split(/\s|-/);
232
+ const codePoints = hexPoints.map((hex) => parseInt(hex, 16));
233
+ const finalEmoji = String.fromCodePoint.apply(null, codePoints);
234
+ this.$set(this.allEmojis.emojis[key], "hexa", hexPoints.join(""));
235
+ this.$set(this.allEmojis.emojis[key], "finalEmoji", finalEmoji);
236
+ }
237
+ i = end;
238
+ if (i < keys.length) {
239
+ if (window.requestIdleCallback) requestIdleCallback(process);
240
+ else setTimeout(process, 0);
241
+ }
242
+ };
243
+ if (window.requestIdleCallback) requestIdleCallback(process);
244
+ else setTimeout(process, 0);
245
+ } catch (e) {
246
+ console.error("Erro ao gerar os emojis em chunks", e);
247
+ }
248
+ },
249
+ loadEmojis() {
250
+ try {
251
+ if(!this.hasLoading) {
252
+ this.loading = false;
253
+ return
254
+ }
255
+ this.emojiHeaders();
256
+ this.processEmojisInChunks();
257
+ this.loading = false;
258
+ } catch (e) {
259
+ console.error("Erro ao carregar os emojis");
260
+ console.error(e);
261
+ }
262
+ },
263
+ getRecentEmojis() {
264
+ const recentEmojis = localStorage.getItem("recent-emojis");
265
+ if (recentEmojis) return recentEmojis.split(",");
266
+ return [];
267
+ },
268
+ setEmojiOnLocalStorage(emojiKey) {
269
+ try {
270
+ let finalStr = "";
271
+ const recentEmojis = localStorage.getItem("recent-emojis");
272
+ if (recentEmojis) {
273
+ const arrRecent = recentEmojis.split(",");
274
+ if (!arrRecent.includes(emojiKey)) {
275
+ if (arrRecent.length < 20) {
276
+ finalStr = `${emojiKey},${recentEmojis}`;
277
+ } else {
278
+ arrRecent.pop();
279
+ finalStr = `${emojiKey},${arrRecent.join(",")}`;
280
+ }
281
+ }
282
+ } else {
283
+ finalStr = `${emojiKey}`;
284
+ }
285
+ if (finalStr) {
286
+ localStorage.setItem("recent-emojis", finalStr);
287
+ const finalArr = finalStr.split(",").filter((str) => {
288
+ return str ? str : false;
289
+ });
290
+ this.allEmojis.categories[0].emojis = finalArr;
291
+ }
292
+ } catch (e) {
293
+ console.error("Erro ao setar o emoji no localStorage");
294
+ console.error(e);
295
+ }
296
+ },
297
+ addEmoji(emoji, emojiKey) {
298
+ this.setEmojiOnLocalStorage(emojiKey);
299
+ this.$emit("insert-emoji", emoji);
300
+ },
301
+ pickerHeaderHandler(e, id) {
302
+ try {
303
+ const container = this.$refs["sm-scroll"];
304
+ const target = this.$el.querySelector(`#${id}`);
305
+ if (!container || !target) {
306
+ this.categoriaSelecionada = id;
307
+ return;
308
+ }
309
+ const containerRect = container.getBoundingClientRect();
310
+ const targetRect = target.getBoundingClientRect();
311
+ const offset = targetRect.top - containerRect.top + container.scrollTop;
312
+ container.scrollTo({ top: offset, behavior: "smooth" });
313
+ this.categoriaSelecionada = id;
314
+ } catch (e) {
315
+ console.error("Erro ao mudar de categoria", e);
316
+ }
317
+ },
318
+ filterEmojis() {
319
+ if (!this.search.trim()) return (this.filteredList = []);
320
+
321
+ const rawList = [];
322
+ for (let key in this.allEmojis.emojis) {
323
+ const emoji = this.allEmojis.emojis[key];
324
+ const { a } = emoji;
325
+ const search = this.search.toUpperCase();
326
+ const upperA = a.toUpperCase();
327
+ if (upperA.indexOf(search) >= 0) rawList.push(emoji);
328
+ }
329
+ this.filteredList = rawList;
330
+ },
331
+ },
332
+ };
333
+ </script>
334
+
335
+ <style>
336
+ .box-shadow {
337
+ -webkit-box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2),
338
+ 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
339
+ -moz-box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2),
340
+ 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
341
+ box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14),
342
+ 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
343
+ }
344
+
345
+ .sm-emoji-picker {
346
+ width: 306px;
347
+ height: 250px;
348
+ z-index: 2;
349
+ border: 1px solid #ccc;
350
+ border-radius: 5px;
351
+ background-color: #fff;
352
+ display: flex;
353
+ flex-direction: column;
354
+ }
355
+
356
+ .sm-emoji-picker.small {
357
+ height: 40px!important;
358
+ }
359
+
360
+ .sm-emoji-picker.small .sm-emoji-scroll {
361
+ height: 100%;
362
+ max-height: 100%;
363
+ overflow: hidden;
364
+ }
365
+ .sm-emoji-picker.small .sm-emoji-scroll .sm-emoji-group.small {
366
+ justify-content: center;
367
+ align-items: center;
368
+ flex-wrap: nowrap;
369
+ }
370
+
371
+ .add-more {
372
+ --size: 26px;
373
+ background: #f0f0f0;
374
+ border: 1px solid #ccc;
375
+ border-radius: 50%;
376
+ width: var(--size);
377
+ min-width: var(--size);
378
+ height: var(--size);
379
+ min-height: var(--size);
380
+ display: flex;
381
+ justify-content: center;
382
+ align-items: center;
383
+ font-size: 16px;
384
+ font-weight: bold;
385
+ }
386
+
387
+ .sm-emoji-header {
388
+ width: 100%;
389
+ display: flex;
390
+ align-items: center;
391
+ justify-content: space-between;
392
+ margin: 10px 0;
393
+ border-bottom: 1px solid #ccc;
394
+ }
395
+
396
+ .sm-emoji-link {
397
+ padding: 0 5px 5px 5px;
398
+ display: flex;
399
+ justify-content: center;
400
+ align-items: center;
401
+ cursor: pointer;
402
+ opacity: 0.9;
403
+ transition: all 200ms;
404
+ border-bottom: 2px solid transparent;
405
+ }
406
+ .sm-emoji-link > span svg {
407
+ margin: 0;
408
+ padding: 0;
409
+ fill: #999;
410
+ }
411
+ /* force no-fill for stroke-based icons and the last two header svgs */
412
+ .sm-emoji-link > span svg[stroke],
413
+ .sm-emoji-header .sm-emoji-link:nth-last-child(-n+2) > span svg {
414
+ fill: none !important;
415
+ }
416
+
417
+ /* hover/active: filled icons get fill; stroke icons keep no fill and change stroke color */
418
+ .sm-emoji-link:hover > span svg:not([stroke]),
419
+ .sm-emoji-link.active > span svg:not([stroke]) {
420
+ opacity: 1;
421
+ fill: #666;
422
+ }
423
+
424
+ .sm-emoji-link:hover > span svg[stroke],
425
+ .sm-emoji-link.active > span svg[stroke] {
426
+ opacity: 1;
427
+ fill: none !important;
428
+ stroke: #666;
429
+ }
430
+
431
+ .sm-emoji-scroll {
432
+ width: 100%;
433
+ height: calc(100% - 52px);
434
+ max-height: calc(100% - 52px);
435
+ scroll-behavior: smooth;
436
+ overflow-y: auto;
437
+ overflow-x: hidden;
438
+ scrollbar-color: #888 rgba(0, 0, 0, 0.2);
439
+ scrollbar-width: 8px;
440
+ position: relative;
441
+ }
442
+ .sm-emoji-scroll::-webkit-scrollbar {
443
+ width: 8px;
444
+ }
445
+
446
+ .sm-emoji-scroll::-webkit-scrollbar-track {
447
+ background-color: rgba(0, 0, 0, 0.2);
448
+ }
449
+
450
+ .sm-emoji-scroll::-webkit-scrollbar-thumb {
451
+ transition-duration: 0.5s;
452
+ background-color: #666;
453
+ }
454
+
455
+ .sm-emoji-scroll::-webkit-scrollbar-thumb:hover {
456
+ background-color: #555;
457
+ }
458
+
459
+ .sm-emoji-search {
460
+ width: 100%;
461
+ display: flex;
462
+ align-items: center;
463
+ justify-content: center;
464
+ position: sticky;
465
+ top: 0;
466
+ z-index: 1;
467
+ background: #fff;
468
+ padding-bottom: 10px;
469
+ }
470
+ .sm-emoji-search > input {
471
+ width: 90%;
472
+ outline: none;
473
+ border: 1px solid #ccc;
474
+ border-radius: 2.5px;
475
+ padding: 5px 10px;
476
+ transition: border 200ms;
477
+ }
478
+ .sm-emoji-search > input:focus,
479
+ .sm-emoji-search > input:active,
480
+ .sm-emoji-search > input:hover {
481
+ outline: none;
482
+ border: 1px solid #999;
483
+ }
484
+ .sm-emoji-search.sticky {
485
+ position: fixed;
486
+ width: 310px;
487
+ background-color: #fff;
488
+ }
489
+
490
+ .sm-emoji-selection {
491
+ width: 100%;
492
+ margin-bottom: 10px;
493
+ }
494
+ .sm-emoji-title {
495
+ width: 100%;
496
+ display: flex;
497
+ justify-content: flex-start;
498
+ align-items: center;
499
+ background-color: #f7f7f7;
500
+ padding: 5px 0;
501
+ white-space: nowrap;
502
+ text-overflow: ellipsis;
503
+ overflow: hidden;
504
+ }
505
+ .sm-emoji-title svg {
506
+ margin: 0 5px;
507
+ }
508
+
509
+ .sm-emoji-group {
510
+ width: 100%;
511
+ display: flex;
512
+ flex-wrap: wrap;
513
+ font-size: 22px;
514
+ }
515
+
516
+ .sm-emoji-item {
517
+ cursor: pointer;
518
+ opacity: 0.8;
519
+ transition: opacity 200ms;
520
+ margin: 3.5px;
521
+ }
522
+ .sm-emoji-item:hover {
523
+ opacity: 1;
524
+ }
525
+ </style>