پرتوپرتو

useWhatsNew

حالت «دیده‌شده» برای سطح آخرین تغییرات — مبتنی بر ترتیب، با بازیابی دومرحله‌ای، بدون گیر کردن روی روشن یا خاموش

کدام سطح را می‌خواهید؟

اعلام تغییرات محصول تصمیم می‌گیرد کدام ریلیز سزاوار کدام سطح است و بودجهٔ وقفه را تعیین می‌کند — از آنجا شروع کنید. WhatsNew* زنگوله و پنل و مودال است، ReleaseTimeline صفحهٔ کامل، و useWhatsNew حالت «دیده‌شده».

معرفی

useWhatsNew تنها جایی است که منطق «کدام یادداشت را کاربر ندیده» زندگی می‌کند. WhatsNewBell، WhatsNewPanel و WhatsNewSpotlight از آن تغذیه می‌شوند و خودشان هیچ حالتی نگه نمی‌دارند.

چه زمانی استفاده کنیم

  • وقتی سطح «آخرین تغییرات» را در پوستهٔ یک محصول سوار می‌کنید
  • وقتی می‌خواهید حالت «دیده‌شده» را روی سرور نگه دارید (حالت کنترل‌شده)

چه زمانی استفاده نکنیم

  • برای اعلان‌های کاری کاربر — آن NotificationCenter است و حالت خودش را دارد
  • برای هر «آیا این را دیده‌ای؟» عمومی؛ این هوک قواعد مخصوص یادداشت انتشار را دارد (کانال، تاریخ آینده، مودالِ یک‌بار)

هوک را فقط یک‌بار صدا بزنید

دو نمونه یعنی دو واترمارک مستقل روی یک کلید ذخیره‌سازی. آن‌وقت «خوانده شد» در پنل، نشانهٔ روی زنگوله را خاموش نمی‌کند و هر دو برای نوشتن روی یک کلید مسابقه می‌دهند. یک‌بار در بالاترین نقطه صدایش بزنید و مقدارهای مشتق‌شده را پایین بدهید.

استفاده

'use client'

import { useWhatsNew } from '@partodata/ui'

import { whatsNewFeed } from '@/content/whats-new'

const feed = useWhatsNew({ notes: whatsNewFeed.notes, productKey: whatsNewFeed.product })

برای بارِ سبک‌تر می‌توانید از subpath استفاده کنید: import { useWhatsNew } from '@partodata/ui/hooks/use-whats-new'.

حالت کنترل‌شده

با دادن lastSeenId مالکیت حالت را می‌گیرید و هوک دیگر به localStorage دست نمی‌زند. این مسیر ارتقا به حالت «دیده‌شده»‌ی سروری و مشترک بین دستگاه‌هاست:

const feed = useWhatsNew({
  notes: whatsNewFeed.notes,
  lastSeenId: user.whatsNewSeenId,
  onSeen: (id) => saveSeenId(id),
  lastSpotlightId: user.whatsNewSpotlightId,
  onSpotlightShown: (id) => saveSpotlightId(id),
})

قواعدی که این هوک تضمین می‌کند

  • مبتنی بر ترتیب است، نه برابری. «دیده‌نشده» یعنی یادداشت‌هایی که در آرایه بالاتر از واترمارک‌اند. پس آرایه باید همیشه از جدید به قدیم باشد.
  • اولین بازدید سکوت است. بدون مقدار ذخیره‌شده، جدیدترین شناسه نوشته می‌شود و چیزی نشان داده نمی‌شود — کاربر تازه نباید با انبوه اعلان روبه‌رو شود.
  • بازیابی دومرحله‌ای. اگر شناسهٔ ذخیره‌شده دیگر وجود نداشته باشد، از seenAt استفاده می‌شود؛ فقط اگر آن هم نشد، همه‌چیز خوانده‌شده علامت می‌خورد.
  • واترمارک خودبه‌خود جلو نمی‌رود. فقط یک کنشِ کاربر آن را حرکت می‌دهد — نه گذر زمان، نه یادداشت silent تازه.
  • مودال واترمارک را حرکت نمی‌دهد. markSpotlightShown یک اسکالر جداگانه می‌نویسد، چون مودال فقط یک یادداشت را نشان داده و جلو بردن واترمارک، اعلان‌های قدیمی‌ترِ دیده‌نشده را مصرف می‌کرد.
  • تا بعد از hydration ساکت است. isReady پیش از mount false است، پس نشانه فقط در یک رندرِ پس از hydration ظاهر می‌شود و ناسازگاری SSR رخ نمی‌دهد.

ورودی

Prop

Type

خروجی

نامتوضیح
notesیادداشت‌های منتشرشده (تاریخ‌های آینده کنار گذاشته شده‌اند)، از جدید به قدیم
unseenهر چه بالای واترمارک است — شامل یادداشت‌های silent
announcedزیرمجموعه‌ای که اجازه دارد نشانه را روشن کند؛ مودالِ نمایش‌داده‌شده از آن حذف می‌شود
announcedCountهمان را بشمارید و به WhatsNewBell بدهید
hasUnseenannouncedCount > 0
spotlightتنها مودالی که باید باز شود، یا null. هرگز روی هم انباشته نمی‌شود
lastSeenIdواترمارک فعلی
isFirstVisitهنگام آماده‌شدن هیچ واترمارکی وجود نداشت
isReadyتا پس از hydration false است (فقط در حالت کنترل‌نشده)
markSeen(id)واترمارک را به آن یادداشت و هر چه قدیمی‌تر می‌برد
markAllSeen()واترمارک را به جدیدترین یادداشت می‌برد. پنل هنگام باز شدن این را صدا می‌زند
markSpotlightShown(id)ثبت می‌کند کدام مودال نمایش داده شده. به واترمارک دست نمی‌زند

ذخیره‌سازی

کلید parto:whats-new:<productKey> و مقدارش { v: 1, lastSeenId, seenAt, lastSpotlightId? } است. v راه مهاجرت است و seenAt مسیر بازیابی دوم. مقدار خراب یا ناخوانا مثل «اولین بازدید» رفتار می‌کند، نه مثل «همه‌چیز تازه است».

هوک‌های مرتبط

  • useLocalStorage — لایهٔ زیرین ذخیره‌سازی
  • WhatsNew — کامپوننت‌هایی که این هوک تغذیه‌شان می‌کند و راهنمای کامل ادبیات یادداشت‌ها