Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 27, 2022 12:37 am GMT

Five whopping-useful web dev tips I used in my newest project

I planned this project for a while, and finally just got it done. In this project, I completely remade Replit Apps with a whole bunch of features.

https://replverse.ironcladdev.repl.co/

So originally, replit apps had no limitations on what image could be uploaded for a cover image and the original algorithm left some projects either trending for months on end (one of mine is still trending after eight months ) or nobody sees your project.

This created a problem that some rickrolls, pranks, and other low-quality projects would trend forever. I decided to change that by creating a new algorithm, adding some highly-requested features, and many more beneficial attributes.

Let's get into the tips!

1. Making a feed/hotlist algorithm

If you've ever wondered how to make a constantly-updating feed or hotlist algorithm, you've found the right place.

As an example, posts on dev.to constantly update, the most popular ones getting bumped higher and higher to the top of the list the more likes they get every day. Older posts that don't get as many reactions over time slowly fall to the bottom.

Each post has a z-score that represents the popularity of it over time. As time goes on, the z-score will drop and the post wills top trending.

First, start by creating some database schemas. In this one, I'll just use a title, likes, views, an array for holding the social data, and finally the z-score.

{  title: String,  likes: Number,  views: Number,  sData: Array,  z: Number}

An example post would be something like the example below. By default, I start the z-score out with a default of ten.

{  title: "Post",  likes: 0,  views: 0,  sData: [[0,0],[0,0]], //make sure sData has two nested arrays!  z: 10}

Now for the algorithm.

function testTrend(t, y, z) {  let T = (t[1] / (t[0] + 1) * (t[1] + 5));  let Y = (y[1] / (y[0] + 1) * (y[1] + 5));  let Z = z||10;  if (T - Y <= 0) {    Z -= Math.abs(T - Y);  } else {    Z += Math.abs(T - Y) / 2;  }  return (Number(Z.toFixed(2))) - 0.25;}

The t (today) parameter is an array of two elements [views, likes] and so is the y (yesterday) parameter.
I am just using "yesterday" and "today" as examples. Of course you could set the algorithm to update every fifteen minutes or so.

The last parameter z is for the z-score of your database item. Just plug the correct value in.

In this example, I will be using mongoose.js with mongodb for the trend algorithm. You should be able to relate with another javascript database driver easily.

let posts = await Post.find({}, '_id'); // find and get every post's _id field    for(var i = posts.length; i--;){ // loop through all of the posts      let id = posts[i]._id; // get the ID of the post      let _post = await Post.findOne({_id: id}); //get one post      let postStats = _post.sData[1]; // get latest social stats      let viewsToday = _post.views + postStats[0];      let likesToday = _post.likes + postStats[1];      let newStat = [postStats, [viewsToday, likesToday]]; //update the stats to get the latest amount of likes and views      _post.sData = newStat; // set the social data to the current latest amounts of likes and views over time      let prevZ = _post.z; //get the z-score of the post      _post.z = testTrend(newStat[1], newStat[0], prevZ); //calculate the new z-score      _post.save(); //save    }

That might've been a bit confusing to understand. Overall, the algorithm calculates how many likes and views a post gets over time and recalculates a z-score. If there are more likes and views then the previous update, the z-score increases and vice-versa.

Now to update this every once in a while.
Basically, what I did was just hook the hotlist algorithm up to an api route and stick it into https://easycron.com.

Every time the api route is called, it updates the posts. If you have a lot of users using your application, you'll see the trend algorithm working.

Unfortunately, this isn't exactly the most accurate algorithm and sometimes goes a bit haywire. Feel free to adjust it and find the best results.

2. Capturing a snapshot of a website

I literally pulled my hair out trying to find the solution. Just before I went bald, I found a thing on heroku that you could just run and deploy. This really doesn't count as me "coming up with a solution" since I just found it, but man, did this make my life easy!

I launched the heroku app and literally all you have to do is just make a GET request to https://webshotty.herokuapp.com/ and you will get a png base64 string that displays the website image.

fetch("https://webshotty.herokuapp.com/?url=https://google.com")  .then(r => r.json())  .then(data => {    document.getElementById("my-image").src = data.image;  })

3. User Following

This project isn't suited for like production-level production, so I used a JSON file for this.

To make it so that users can follow each other, all you need is a JSON file (or database if you are using it for production) and some way to display who follows who.

An example of the type of schema you will need to use is shown below:

{  user: String,  userAvatar: String, //image url  follows: String,  followAvatar: String //image url}

For example, if John Doe follows Jane Doe, this is how we'll set the schema:

{
user: "John Doe",
userAvatar: "https://domain.com/avatars/john-doe.png",
follows: "Jane Doe",
followAvatar: "https://domain.com/avatars/jane-doe.png"
}

All these objects will be stored in the json file as an array or in the database as a document.

To get the followers of a certain user, run through the array and filter out all the follows that match a user's name.

let followersOfJohnDoe = allFollowers.filter(f => f.follows === "John Doe")

And to get who John Doe follows, do it the other way around.

let followersOfJohnDoe = allFollowers.filter(f => f.user === "John Doe")

That's basically it!

4. Notifications

This example is for basic notifications. Not SMS or email notifications although you could easily hook up those.

As for notifications, we have the fields Title, Link (when a user clicks on it), Icon, Description, who it is for, and if it has been read.

{  title: String,  link: String,  icon: String, //url  description: String,  read: Boolean, //defaults to false  userFor: String/Number/ObjectID // user's id}

Some examples from the project
Notification examples

It should be pretty simple for you to add a notification to the database and display it to a user. I created a global function to write one that is accessible all over the app's backend and immediately sends one to a certain user.

After collecting all the notifications that are unread and are for a particular user, you can display it and create a function that marks them as read.

5. Tag Input

It's always fun to tag your post on DEV or anywhere else, but it seems a bit difficult if you tried to make one, eh?
It looks hard, but in fact is really simple.

Luckily, I made a handy react component for you that works like magic.

First, import your stuff.
import { useState, useRef } from 'react';

Next, create the component.

function TagInput(){  return (<div>          <div></div>          <input/>        </div>);}

Now assign a ref to your component. When tags get long, this should overflow automatically. We'll need to autoscroll to the end once that happens.
Also, let's make our state handlers.

function TagInput(){  const [tags, setTags] = useState([]); // array of tags  const [t, setTag] = useState(""); // the input (current tag)  const inputRef = useRef(null);  return (<div ref={inputRef}>          <div></div>          <input/>        </div>);}

Now, let's just go overkill and add all the event handlers in (yes, it's ugly).

function TagInput(){  const [tags, setTags] = useState([]); // array of tags  const [t, setTag] = useState(""); // the input (current tag)  const inputRef = useRef(null);  return (<div className={styles.tagWrapper}>          <div className={styles.tags}>            {tags.map(x => <div onClick={() => {              setTags(tags.filter(y => y !== x));              setData({                tags: tags.filter(y => y !== x)              })            }} className={styles.tag} key={x}>{x}</div>)}           </div>          <input placeholder="Add Tags" maxLength={25} className={styles.tagInput} onKeyUp={(e) => {            if((e.key === 'Enter' || e.key === ',') && tag.length > 0 && tags.length < 5){              setTags([...new Set([...tags, tag])]);              setTag("");              setData({                tags: [...new Set([...tags, tag])]              })            }          }} onChange={(e) => {              setTag(e.target.value.replace(/\s/g,"-").replace(/[^a-z0-9\-]/g,""))          }} value={tag}/>        </div>);}

All the handlers and listeners are there for you. Have fun adding the CSS >:)

Well, that's it for today. If you liked it, be sure to give this post a couple reactions and do me a favor by giving the project a like on replit :)

I'm in a hurry to regrow the hair I've pulled out of my head.
Happy coding y'all!


Original Link: https://dev.to/ironcladdev/five-whopping-useful-web-dev-tips-i-used-in-my-newest-project-564b

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To