ViewStockImages

src/components/stock-image-card/ViewStockImages.vue
Media High 3 usos

Galeria de imagens de estoque do chat. Exibe uma grade de thumbnails a partir de props.images com zona de upload integrada. Ao clicar em uma imagem, abre popup de seleção "Imagem ou Figurinha" — exceto em commentMode, que envia direto. Novo upload passa pelo ImageCropper, exceto .gif e .webp que entram direto no stock. Imagens .webp só podem ser enviadas como figurinha ou comentário interno.

gallery
grade + upload
upload-in-progress
Upload em andamento
crop-open
activeCrop = true
selector-open
activeSelector = true
3 props
2 eventos
3 usos

Galeria de Estoque (modo chat)

Estado padrão. O primeiro item da grade é sempre a zona de upload (borda tracejada). Os demais são thumbnails 8rem × 8rem das imagens já cadastradas no stock, cada um com botão X de remoção. O componente fica visível enquanto showImagesStock for true no pai.

Contexto real: envolvido em <div id="grid-stock" v-show="showImagesStock"> em Index.vue:659. O modo :comment-mode é dinâmico — muda conforme o atendente alterna entre chat e comentário interno.
Real Index.vue:659
<div id="grid-stock" ref="grid-stock" v-show="showImagesStock">
  <view-stock-images
    :images="imagesStock"
    :comment-mode="commentActive"
    @on-send-image="sendImage"
    @on-send-sticker="sendFile"
  ></view-stock-images>
</div>

Popup Seletor (Imagem / Figurinha)

Aparece ao clicar em um thumbnail quando commentMode = false. Controlado por activeSelector = true. Para imagens normais (jpg/png/gif), oferece as duas opções. Para .webp, apenas figurinha é permitida — com aviso explicativo.

Imagem normal (jpg/png/gif)
Enviar como:
preview da imagem
.webp — só figurinha disponível
Enviar como:
imagem.webp
Restrição .webp: Imagens com extensão .webp só podem ser enviadas como figurinhas.
Sintético ViewStockImages.vue — activeSelector
<!-- vs-popup controlado por activeSelector -->
<vs-popup
  class="chat-upload-image-popup"
  title="Enviar como:"
  :active.sync="activeSelector"
>
  <!-- Exibe aviso e bloqueia botão "Imagem" se url.endsWith('.webp') -->
  <!-- "Imagens com extensão .webp só podem ser enviados como figurinhas." -->

  <vs-button @click="$emit('on-send-image', 'image', selectedUrl)">
    Imagem
  </vs-button>
  <vs-button @click="$emit('on-send-sticker', 'sticker', selectedUrl)">
    Figurinha
  </vs-button>
</vs-popup>

Modo Comentário (comment-mode)

Quando :comment-mode="true", o popup seletor não é exibido ao clicar num thumbnail — a imagem é enviada diretamente via @on-send-image. O evento @on-send-sticker nunca é emitido neste modo. Imagens .webp em commentMode são enviadas como comentário interno sem exibir nenhum popup.

comment-mode ativo Clicar na imagem envia direto, sem popup
.webp em commentMode: "Imagens com extensão .webp serão enviadas somente como comentário interno." Nenhum popup é exibido — a imagem vai direto para o chat interno.
Sintético uso com comment-mode fixo
<!-- Exemplo sintético — no admin comment-mode é dinâmico (:comment-mode="commentActive") -->
<!-- Use comment-mode fixo para chat interno onde figurinha não é relevante -->
<view-stock-images
  :images="imagesStock"
  :comment-mode="true"
  :max-image-size="5"
  @on-send-image="sendImage"
></view-stock-images>

Upload com ImageCropper

Ao fazer upload de um .jpg ou .png, o popup do ImageCropper é aberto (activeCrop = true). O atendente ajusta o recorte e confirma. Ao salvar, o dispatch stockImages/add é chamado com a URL e caption. .gif e .webp pulam o cropper e vão direto ao stock.

Recortar Imagem
Formatos que pulam o cropper: .gif e .webp são adicionados diretamente ao stock via stockImages/add sem abrir o ImageCropper.
Sintético ViewStockImages.vue — activeCrop
// Upload handler (simplificado)
onUploadFile(file) {
  const ext = file.name.split('.').pop().toLowerCase();

  if (ext === 'gif' || ext === 'webp') {
    // Pula cropper — adiciona direto ao stock
    this.$store.dispatch('stockImages/add', {
      url: file.dataURL,
      caption: file.name
    });
    return;
  }

  // jpg/png: abre ImageCropper
  this.cropSrc = file.dataURL;
  this.activeCrop = true;
},

// vs-popup do ImageCropper controlado por activeCrop
// <image-cropper :src="cropSrc" @on-crop-image="handleCrop" />

handleCrop(croppedUrl) {
  this.$store.dispatch('stockImages/add', { url: croppedUrl });
  this.activeCrop = false;
}

API

Props

Prop Tipo Default Descrição
images Any null Array de { id, url, caption? }. Grade de thumbnails exibida.
maxImageSize Number 5 Limite em MB para upload. Passado ao componente Upload interno.
commentMode Boolean false true: envia imagem diretamente sem popup seletor. .webp vira comentário interno.

Eventos emitidos

Evento Payload Descrição
@on-send-image ('image', url) Usuário escolheu enviar como imagem. Emitido em commentMode também (direto, sem popup).
@on-send-sticker ('sticker', url) Usuário escolheu enviar como figurinha. Nunca emitido quando commentMode = true.

Parent events

Evento Descrição
$parent.$on('closeAllPopUps') O componente escuta este evento no pai para fechar todos os popups internos abertos (activeSelector, activeCrop). Listener registrado em created e removido em beforeDestroy.

Fluxo de upload

1. Upload
automático, limit=1
jpg/jpeg/gif/jfif/png/webp
2. Verificar ext.
.gif ou .webp
pula cropper
3. ImageCropper
apenas jpg/png
activeCrop = true
4. stockImages/add
url + caption
via Vuex dispatch
Comportamento especial — .webp

Restrição do WhatsApp: imagens .webp não podem ser enviadas como imagem normal.

Popup padrão (commentMode = false): "Imagens com extensão .webp só podem ser enviados como figurinhas." — apenas o botão Figurinha é exibido.

commentMode = true: "Imagens com extensão .webp serão enviadas somente como comentário interno." — sem popup, envia direto como comentário.

Dependências

DependênciaUso
vs-popup (×2)Popup seletor (activeSelector) + popup ImageCropper (activeCrop)
vs-col, vs-buttonLayout interno e botões de ação
Upload componentZona de upload, automatic, limit=1, accept: jpg/jpeg/gif/jfif/mpeg/png/web/webp
ImageCropper componentRecorte de imagem antes de adicionar ao stock (apenas jpg/png)
Vuex stockImagesfetch (lista inicial), add (novo upload), remove (botão X)

Usado em

ArquivoStatus
src/views/chat-attendance/Index.vue:659 Ativo
src/views/chat-attendance/NewIndex.vue Ativo
src/views/internal-chat/InternalChatMessage.vue Import morto (não usado no template)