ይህን ባህሪ ማበርከት እስከ ሦስት ቀናት ወሰደ፤ ሁሉም ነገር ከ0 ጀምሮ ነበር። ብቻ የምላሾች ባህሪ ነው — ከታች ያሉ እንቅስቃሴዎች ይታያሉ 😁
ዝርዝር ትንተና ሳይኖር በቀጥታ ዳታቤዝ፣ ሙከራ/ስህተት እና ማሻሻል ጀመርሁ። ሀሳቡ በፍጥነት መኮድ ጀመር ነበር 😂
በዚህ ጽሑፍ ውስጥ ባህሪያቱን እና ሀሳቡን እገልጻለሁ፤ ነገር ግን እንደ መመሪያ በደረጃ አይደለም።
ምናልባት እናንተም ልትሞክሩ ትፈልጋላችሁ፤ ትንሽ ትንሽ መውሰድ ይቻላል፣ ግን የጥሩውን ብቻ ይውሰዱ።
እንግዲያ ቀጥለን እንጀምር...
ባህሪያት
መጀመሪያ የምላሾቹ ጠቅላላ መልክ እንዴት እንደሚሆን አሰብኩ።
እና በመጠቀም የምንፈልጋቸው ባህሪያት እነዚህ ናቸው፦
-
Multiple Reactions
claps፣ wow ወዘተ አሉ፤ ወደፊት አዲስ ምላሶች ለመጨመር ቀላል እንዲሆን ተዘጋጅቷል።
-
Batch Reactions
ተመሳሳይ ምላሽ ብዙ ጊዜ መስጠት ይቻላል፣ ለምሳሌ 20x claps፣ 10x wow።
-
Section Reactions
ተጠቃሚው ምላሽ የሰጠበትን ክፍል መለየት ይቻላል፣ ለምሳሌ በ**'ባህሪያት'** ክፍል 10x claps።
ኮንሰፕት (መርሀግብር)
ብዙ ጊዜ የወሰደው REST API መገንባት፣ ማሻሻል እና የዳታቤዝ ስኬማ ማቀናበር ነበር፤ የBE ክፍል ስራዎች ብዙ ነበሩ።
ነገሮች ፍጹም አይሆኑም ሊሆን ይችላል — ይቅርታ፣ የBE ሰው አይደለሁም ✌
ዳታቤዝ
ከሶስት ዓመት በኋላ እንደገና ከዳታቤዝ ጋር ተሳትፌ ጀመርሁ። መጨረሻ ጊዜ ከዩኒቨርሲቲ መጨረሻ ፕሮጀክት ጋር ነበር።
መጀመሪያ የሆስቲንግ መድረክ መምረጥ ነበር። SQL ወይም NoSQL አልተወሰነም — ሙከራ ነበር፣ ስለዚህ የተካፈለ MongoDB Atlas እትም መረጥኩ።
ORM ለመጠቀም Prisma ተጠቅመሁ፣ ስለዚህ ወደ ሌላ ዳታቤዝ መቀየር አይደክምም ብዬ አመንሁ።
እንጀምር ወደ ዳታቤዝ ስኬማ። እዚህ በምላሾች ባህሪ ብቻ እንተኮራለን፤ የviews እና shares መስኮቶች አሉ ግን አልጨምርኋቸውም።
መጀመሪያ የContentMeta ሰንጠረዥ አሰራሁ — የፖስቱን መረጃ ለማከማቸት።
ርዕስ፣ ቀን ወዘተ ማከማቸት አያስፈልግም፤ የፖስቱ መረጃ በMDX በአካባቢ ይፈጠራል፣ ስለዚህ slug ብቻ ይቀመጣል።
model ContentMeta {
id String
slug String
createdAt DateTime
}
ከዚያ አስፈላጊው ይህ ነው፤ Reaction ሰንጠረዥ — የምላሾችን መዝግብ ለማከማቸት።
model Reaction {
id String
type ReactionType
section String
count Int
sessionId String
createdAt DateTime
contentId String
}
enum ReactionType {
CLAPPING
THINKING
AMAZED
}
በቀስታ እንከፍላው፦
-
typeእጅግ አስፈላጊ ነው፤ ብዙ ምላሾች ስንጠቀም
typeአስፈላጊ ነው። የውሂብ አይነቱ ቀድሞ የተገለጸ ኤናምReactionTypeነው —CLAPPING፣THINKING፣AMAZEDብቻ።አዲስ ምላሾችን ለመጨመር ወደ ኤናሙ ንጥል ይጨምሩ ወይም የውሂብ አይነቱን ወደ String ቀይሩ እና ማንኛውንም ኢሞጂ ይጠቀሙ።
ለምን አዲስ ሰንጠረዥ ግንኙነት አንሰራ?
ይቻላል፣ ግን ኩዌሪ ይዘርጋል ብዬ አስባለሁ፤ ኤናም በቂ ነው እና type‑safety ይረዳል ✌
-
sectionተጠቃሚው ሲጫን ያለ ክፍል ርዕስ ብቻ ይቀመጣል። ለምሳሌ የ'ዳታቤዝ' ርዕስ ከተነበበ እዚህ 'database' ይመዘገባል።
IntersectionObserver እንጠቀማለን — ርዕሶችን እናይ እና መጨረሻው 'isIntersecting' ይመዘገባል።
-
countይህ የተሰበሰበ ብዛት ነው። ክሊክ ጊዜ በአንድ ጊዜ API አይልክም፤ ትንሽ milliseconds ይዘገያል (debounce).
በቀላሉ፦ በአጭር ጊዜ ውስጥ ብዙ ጊዜ ሲጫን መጀመሪያ ይሰበሰባል (ምሳ. 10 ጊዜ) ከዚያ ወደ API ይላካል እና ቁጥሩ በ
countውስጥ ይቀመጣል።ከ10 ጊዜ API መጠየቅ እና 10 ተመሳሳይ ረድፎች መፍጠር ይልቅ ይህ የበለጠ ይረባ ነው፣ ማከማቻንም ያቆጥባል።
-
sessionIdማን ምላሽ እንደሰጠ ለመለየት ነው። ስም ወይም መለያ አይደለም፤ የተጠቃሚ አይፒ ነው — ግን በቀጥታ አይቀመጥም። አይፒው በሃሽ እና በsalt ይጠበቃል።
ለምሳሌ ኮድ፦
export const getSessionId = (req) => { const ipAddress = req.headers['x-forwarded-for'] || 'localhost'; // hashes the user's IP address and combines it with // a salt to create a unique session ID that preserves // the user's privacy by obscuring their IP address. const currentSessionId = createHash('md5') .update(ipAddress + process.env.SALT_IP_ADDRESS, 'utf-8') .digest('hex'); return currentSessionId; };ወይም በቀጥታ ለማየት እዚህ ይመልከቱ።
እንግዲህ ለምን sessionId?
ገደብ ለመመዘን ይጠቅማል።
typeእናsessionIdበመቡካት ቁጥር ይቆጠራል። ገደብ ከደረሰ ተጠቃሚው ምላሽ አይጨምርም።
REST API
አንድ መጨረሻ ብቻ ይያዛል — /reactions (POST) የslug፣ type፣ section፣ count ይቀበላል።
የሚላኩ መረጃዎች በFront‑End ይታከማሉ፤ sessionId ግን በAPI ጥያቄ ጊዜ ይጀነሬታል።
እንዲሁም GET /content አለ — የአሁኑን slug የምላሽ ብዛት ዝርዝር ይመልከታል ለኮምፖነንት መጠቀም።
ከሁለቱ ሰንጠረዦች ውስጥ ይህን መረጃ ይወጣል (ምላሽ /content):
{
"meta": {
"reactionsDetail": {
"CLAPPING": 65,
"THINKING": 45,
"AMAZED": 48
}
},
"metaUser": {
"reactionsDetail": {
"CLAPPING": 15,
"THINKING": 15,
"AMAZED": 15
}
},
"metaSection": {
"fitur": {
"reactionsDetail": {
"CLAPPING": 0,
"THINKING": 4,
"AMAZED": 0
}
},
"database": {
"reactionsDetail": {
"CLAPPING": 0,
"THINKING": 0,
"AMAZED": 6
}
},
}
}
meta የሁሉም ተጠቃሚ ጠቅላላ ምላሽ ነው፣ metaUser የአሁኑ ተጠቃሚ ምላሽ ነው፣ metaSection ደግሞ በተወሰነ ክፍል ውስጥ ያለው ብዛት ነው።
እንዴት ስለሆነ ምናልባት metaSection ድርድር አይደለም ትሉ ይሆናል — በFE ኮምፖነንት ክፍል ብቻ እንወስዳለን ስለዚህ metaSection[section] መንበብ ይቀላል እና መስብስ አያስፈልግም 👀
ኮምፖነንት
This is the part that I enjoy the most.
መጀመሪያ ከAPI መረጃ ለመውሰድ SWR እጠቀማለሁ። እንደ ሰነዱ ይህ ነው፦
With SWR, components will get a stream of data updates constantly and automatically. And the UI will be always fast and reactive.
SWR ቀላል እና ጠቃሚ ነው፣ በተለይ ለmutation መረጃ።
አሁን የምላሽ ኮምፖነንትን እንሠራ 🥳
ዝርዝር፦
claps፣wow፣hmmምላሾችን ማሳየት።- በhover ጊዜ የኢሞጂ አኒሜሽን።
- በተደጋጋሚ ክሊክ ጊዜ አኒሜሽን።
- በcounter ላይ አኒሜሽን።
- ገደብ ሲደርስ ኢሞጂ መቀየር።
ለኢሞጂ አኒሜሽን (2) ከዚህ ተጠቅመዋል።
ለአኒሜሽን እንደነበር framer‑motion እጠቀማለሁ 😍
ተጠቃሚው ሲጫን አኒሜሽን ይታያል፤ በonClick ጊዜ የx/y እሴቶች ዘፈቀዱ ናቸው እና በframer‑motion ይታሰሩ።
x እና y ዘፈቀዱ ስለሆኑ ብዙ ጊዜ ሲጫን አንድ አቅጣጫ አይኖርም።
ሙሉ ኮድ ይመልከቱ።
የመጨረሻ ውጤት
ይህ የመጨረሻ ውጤት ነው፤ ምላሽ ይስጡ እስከ ገደብ ድረስ — አኒሜሽኑን ይመልከቱ 😁
ምንም እንኳን styles/ምስሎች/አቀማመጥ/አፈጻጸም ላይ ማሻሻል ቢቀር ከአሁኑ ውጤት ደስ ይላል።
ማጠቃለያ
ይህ ባህሪ በተለይ በBE ክፍል ፈታኝ ቢሆንም ሂደቱን ወድጄ አደረግሁ — ሦስት ቀናት ወሰደ 😁
የተጠቀሙ ቴክ ስታክ/ላይብረሪዎች፦
- MongoDB Atlas ለዳታቤዝ ሆስቲንግ
- Prisma ለORM
- SWR ከAPI መረጃ ለመውሰድ
- Framer Motion ለአኒሜሽን
- Animated Fluent Emoji
ጠብቁ፣ እና የክፍል ምላሾች? API የሚል
metaSectionአለ — ለምን ይጠቅማል?
መረጃው ካለ ጥሩ ነው፤ መፈጸም ገና አልተሟላም ቢሆንም ዕቅድ አለ እና ግልጽ ነው — ተጠብቁ 😁
ምናልባት በTwitter ላይ እንደምንያዘምን ይመስላል፣ ልዩ ፖስት አይኖርም።
እጅግ አመሰግናለሁ እስከ መጨረሻ ስለተነበባችሁ። በሚቀጥለው ሳምንት እንገናኛለን 👋