Wix release the new wix-realtime which allow developers to build interactive apps like chat app, multi-player game etc.
So, In this example i will discuss how we can build a chat app where a user can send a message to person B and person B immediatly get the message.
If you want to test it live here is the link:
https://test.salman2301.com
Overview
Front-end we use custom element, which allows to show the message side by side and also with custome element, we can have a fix height and scroll bar so user can scroll to previous messages. We can use repeater for this but we need to use pagination or infinite scrolling which is why i didn't. On the Backend, we use wix-realtime API with datahook - datahook runs the code when a new row is inserted in the database.
- realtime API allow us to do pub/sub ( publish/ subscriber) where sender or publisher send message to a channel and the reciever or subscriber can reciver the message.
Dataflow
If a user Person A send a message to Person B, the message will be inserted in the database and this runs the afterInsert data hook and the data hook use realtime api to publish to a channel, the name of the channel is same as the Person B user id. In this way, only the person B recieve the message and On the front-end, let's assume that the person B is online and we subscribe to the channel and the name of the channel Is the current user id. We get the user id from wix-user module wixUser.currentUser.id.
Database
Database Name: message Fields:
field_key data
from - USER_ID
to - USER_ID
message - Message
Code
// backend/data.js
import {publish} from 'wix-realtime-backend';
// datahook runs when a new row is inserted in the database
// item contains inserted row information { from: "uuid", to:"uuid", message:"hello"}
export function message_afterInsert(item, context) {
const { from, to, message, _id } = item;
const channel = { name : to};
let data = {
message,
from,
_id
};
// publish which take a channel name and data.
publish(channel, data, {includePublisher: true});
return item;
}
// Page code
import * as realtime from "wix-realtime";
import wixUsers from "wix-users";
import wixData from "wix-data";
import { getUsers, getMe } from "backend/getUsers.jsw";
let lastUserId, lastLoginEmail, lastPicture;
let userId = wixUsers.currentUser.id;
let owner;
$w.onReady(function () {
// $w('#dataset1').onReady(init);
init();
$w("#inSearch").onKeyPress((e) => {
setTimeout(() => {
if (e.key === "Enter") filterMem();
if (e.key === "Escape") {
$w("#inSearch").value = "";
filterMem();
}
}, 40);
});
$w("#ChatElement").setAttribute(
"append-msg",
JSON.stringify({
user: {
name: "salman",
},
msg: " Hello this is a test",
date: new Date().toISOString(),
isOwner: true,
})
);
getMe().then((data) => {
owner = data;
});
});
function init() {
// wix real time
const channel = { name: userId };
realtime.subscribe(channel, newMessage);
// update UI
filterMem();
// events
$w("#repeaterUser").onItemReady(($item, itemData, i) => {
let { loginEmail, picture } = itemData;
$item("#image1").src = picture;
$item("#textEmail").text = loginEmail;
});
$w("#containerUser").onClick((e) => {
switchUser(e.context.itemId);
});
$w("#btnSend").onClick(sendMessage);
$w("#inMessage").onKeyPress((e) => {
const { ctrlKey, key } = e;
if (key === "Enter" && !ctrlKey) {
sendMessage();
}
});
}
async function filterMem() {
let inMember = $w("#inSearch").value || undefined;
getUsers(inMember)
.then((data) => {
$w("#repeaterUser").data = data.items;
if (!lastUserId) {
switchUser(data.items[0]._id);
}
})
.catch(console.error);
}
async function switchUser(toUserId) {
lastUserId = toUserId;
$w("#repeaterUser").onItemReady(($item, itemData, i) => {
let { _id, loginEmail, picture } = itemData;
if (_id === toUserId) {
$item("#imgCurrUser").show();
$w("#textHeadUser").text = `Connected to ${loginEmail}`;
lastLoginEmail = loginEmail;
lastPicture = picture;
refreshMsg();
} else {
$item("#imgCurrUser").hide();
}
});
}
async function newMessage({ payload }) {
appendMsg(payload._id);
}
async function refreshMsg() {
$w("#ChatElement").setAttribute("messages", "[]");
let resMsgs = await wixData
.query("message")
.eq("from", userId)
.eq("to", lastUserId)
.or(wixData.query("message").eq("from", lastUserId).eq("to", userId))
.ascending("_createdDate")
.find();
let msg = resMsgs.items;
let username = lastLoginEmail.split("@")[0];
msg = msg.map((el) => {
let isOwner = userId === el.from;
let userImage = isOwner ? owner.picture : lastPicture;
userImage = encodeURI(userImage);
if (!userImage.startsWith("https://")) userImage = undefined;
return {
_id: el._id,
isOwner: isOwner,
user: {
name: username,
image: userImage,
},
msg: el.message,
date: el._createdDate,
data: el,
};
});
$w("#ChatElement").setAttribute("messages", JSON.stringify(msg));
if (msg.length === 0) {
$w("#textNoMsg").show();
} else {
$w("#textNoMsg").hide();
}
}
async function appendMsg(msgId) {
let resMsgs = await wixData.query("message").eq("_id", msgId).find();
let message = resMsgs.items[0];
console.log({ resMsgs });
let username = lastLoginEmail.split("@")[0];
let isOwner = userId === message.from;
let userImage = isOwner ? owner.picture : lastPicture;
userImage = encodeURI(userImage);
if (!userImage.startsWith("https://")) userImage = undefined;
let msg = {
_id: message._id,
isOwner: isOwner,
user: {
name: username,
image: userImage,
},
msg: message.message,
date: message._createdDate,
data: message,
};
if (!(lastUserId === message.from || lastUserId === message.to)) {
console.error(" No for the current user show alert!");
return;
}
$w("#ChatElement").setAttribute("append-msg", JSON.stringify(msg));
}
async function sendMessage() {
try {
$w("#btnSend").disable();
let msg = $w("#inMessage").value;
if (!msg) return;
let toInsert = {
from: userId,
to: lastUserId,
message: msg,
};
let inserted = await wixData.insert("message", toInsert);
appendMsg(inserted._id);
$w("#btnSend").enable();
$w("#inMessage").value = "";
} catch (e) {
console.log("ERROR : ", e.message);
$w("#btnSend").enable();
$w("#inMessage").value = "";
}
}
For the custome element check my github
https://github.com/Salman2301/wix-chat-component
This tutorial on building a realtime chat app in Corvid is incredibly insightful and provides a comprehensive guide for both beginners and experienced developers alike. The step-by-step instructions are clear and easy to follow, making it a valuable resource for anyone looking to delve into the world of real-time communication. For further exploration, the author suggests checking out additional resources available on their site, making it a great post to read and enhancing your understanding of Corvid development. Be sure to see this site for a deeper dive into the topic. Whether you're creating a chat app for personal use or for your business, this tutorial covers all the essential aspects, from setting up the environment to implementing key features.
Wow, your information is nice we will try this soon and thanks for posting this and keep it up.
_____________________________________
from:- cheap digitizing embroidery
how do i set up the front end elements? please help me
Excellent. Will try.