Contenido del curso
Para lograr enviar un mensaje presionando la tecla Enter, pueden hacer lo siguiente: En MessagesView.vue, el footer lo deje igual, solo agregando un v-on con el evento keyUp:
<footer> <textarea rows="3" v-model="newMessage" @keyup.enter="sendMessage" ></textarea> <button @click="sendMessage"> <Icon icon="carbon:send-alt" /> </button> </footer>
La función sendMessage queda así:
const sendMessage = () => { addMessage({ message: newMessage.value, channelId: channelId.value, }); newMessage.value = ""; scrollToBottom(); };
Y addMessage es una actions (función) en messages.js:
const addMessage = (newMessage) => { messages.value.push({ id: Date.now(), author: 1, message: newMessage.message, timestamp: new Date().toLocaleTimeString(), read: false, channelId: parseInt(newMessage.channelId), }); };
Profesora Diana logre hacer el reto!! comparto mi solución En channels.js añadi este getter => { const profileStore = useProfileStore() return [ { id: profileStore.id, name: profileStore.username, avatar: profileStore.avatar }, ...state.contacts ] }
para usarlo dentro del componente MesaagesView.vue
lo use de la siguiente manera:
const allContacts = computed(() => contactsStore.getAllContacts) <div class="people-list"> <div class="people-item" v-for="p in allContacts" :key="p.id" > <img :src="p.avatar" :alt="p.name" /> </div> </div>
Rene Linares
Hola👋🏻 No me queda algo claro: Por qué para acceder al state dentro del mismo modulo para los getters pasamos el state por parámetro sin embargo para los actions accedemos a través del contexto this? Funcionaría la misma lógica, solo que al revés? Es decir, usar this dentro de un getter para acceder al state y en el caso de los actions pasar el state como un parámetro?
Diana Martinez
Esta es una aplicación de ejemplo, lo que te haga más sentido, si funciona, está bien.
Lavinia Manzanarez
Este es el getter que agregué en el stor de channels:
getChannelTitle: (state) => (channelId) => { return state.channels.find((channel) => channel.id == channelId).name ?? 'No channel name'; }
Lavinia Manzanarez
La parte de los mensajes no me estaba funcionando, en caso de que se encuentren con algo parecido. Lo resolví forzando el valor a tipo numero. En MessagesView.vue:
channelId.value = Number(id);
Axlin Miranda
SANTIAGO OCHOA
mi codigo para mostrar los contactos de una conversacion
const contactsView = computed(() => messagesView.value.reduce((acc, currentValue) => { if (!acc?.includes(currentValue.author.id)) { acc.push(currentValue.author.id) } return acc; }, []) .map(author_id => contactsStore.getContactById(author_id)));
Felix Torres Javier Antonio
Agregué el mismo watch que estaba en la vista de mensajes, para cambiar los titulos del header dinamicamente.
Uriel Solis Salinas
Felix Torres Javier Antonio
Diego Fernando Leyton Ledesma
Hermano una pregunta, ¿Cómo hiciste para ubicar los avatars en el extremo superior derecho?, yo lo intenté asignándole un space-beetwen al contenedor padre mas cercano, pero al estar la etiqueta img dentro de un bucle se ve de esta manera
Ruben Gallegos Hernandez
Saludos, comparto mi solución:
En el store de channels le anexe en el getter:
getChannelById: (state) => (channelId) => { return state.channels.find(channel => channel.id === channelId) } ```En el store de messages le anexe en el getter: ```js getCountContact: (state) => (channelId) => { const contactStore = useContactStore(); return state.messages.filter(message => message.channelId === channelId) .map(message => { const user = contactStore.getContactById(message.author) return { ...user } }) } ```En el archivo MessageView: ```js watch( () => route.params.id, (id) => { channelId.value = Number(id); scrollToBottom(); const channel = channelStore.getChannelById(channelId.value); if (channel) { title.value = channel.name; people.value = messageStore.getCountContact(channelId.value); } }, { immediate: true } );
Respecto a los retos, yo así los solucioné: .
// MessagesView.js // Función para ver los avatares de los contactos que están en el canal const contactsView = computed(() => { const contacts = messagesView.value.map((message) => message.author); // Se obtienen los contactos que enviaron mensajes en el canal return contacts.filter((contact, index) => { // Se filtran los contactos para que no se repitan // contact => Contacto actual // index => Índice del contacto actual return contacts.findIndex((c) => c.id === contact.id) === index; // Se retorna el índice del primer contacto que coincida con el actual }); }); // En el template: <div class="people-item" v-for="contact in contactsView" :key="contact.id" > <img :src="contact.avatar" :alt="contact.name" /> </div>
const updateTitle = () => { const channel = channelsStore.channels.find( (channel) => channel.id === channelId.value ); // Se obtiene el canal actual if (channel) { title.value = channel.name; // Se actualiza el nombre del canal } else { title.value = "Nombre del canal"; } }; watch( // Cuando cambia el ID del canal actual, se actualizan los datos del canal. () => route.params.id, (id) => { channelId.value = parseInt(id); // Se actualiza el ID del canal actual scrollToBottom(); updateTitle(); }, { immediate: true } );
Cualquier duda me pueden preguntar!!
No me la compliqué y para mostrar los contactos, solo agregué un array de canales en el store de contactos.
cree un componente de contactos y solo mostré las fotos.
contacts: [ { id: 1, name: "Tú", avatar: "/avatars/avatar.jpeg", channels:[1,4,5] }, { id: 2, name: "Jason", avatar: "/avatars/avatar-02.jpg", channels:[1,4]}, { id: 3, name: "Janet", avatar: "/avatars/avatar-03.jpg", channels:[1,2]}, ],
Para el nombre del chat creé un getter dentro de channels.js que recibe el channelId, busca por el id y luego retorna solo el nombre.
getters:{ getTitleChannel : (state) => (channelId) => state.channels.find((channel) => channel.id === channelId).name, }
En lo de las imágenes no sabía como quitar los duplicados que obtenía al listar cada autor de la lista de mensajes. Así que me puse a investigar y encontré una solución con filter y findIndex y así pude quitar los duplicados. Este código lo agregé dentro de contacts.js
getters:{ getContactsByChannelId : (state) => (channelId) =>{ const messagesStore = useMessagesStore(); return messagesStore.findMessagesByChannelId(channelId) .map((message)=>{ return state.getContactById(message.author) }) .filter((contact,index,listContacts)=>{ return index == listContacts.findIndex((elementList)=>{ return elementList.id ==contact.id }) }) }, }
Igual cualquier sugerencia es recibida ya que sigo aprendiendo Js 😄