exclude trend/tech/startup from UUID short-circuit + move category badge below date"

This commit is contained in:
Mohamad Mahdi Jebeli 2026-06-21 10:16:52 +03:30
parent 00e834c2d3
commit 5f4782434a
2 changed files with 84 additions and 43 deletions

View File

@ -41,6 +41,19 @@ class HomeWidgetRepository {
} }
} }
/// True when [id] looks like a UUID (e.g. cdaa8830-d03d-420e-9921-4997a44457e9),
/// which means the notification refers to a content from the new
/// content-service (UUID-based) rather than a legacy int-id record.
static bool _isUuid(dynamic id) {
if (id == null) return false;
final s = id.toString().trim();
// Loose check 8-4-4-4-12 hex with dashes, length 36.
final re = RegExp(
r'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$',
);
return re.hasMatch(s);
}
static Future<void> fetchWidget() async { static Future<void> fetchWidget() async {
// RequestService.token = await StorageService.getValue(key: 'token'); // RequestService.token = await StorageService.getValue(key: 'token');
final service = RequestService( final service = RequestService(
@ -223,7 +236,30 @@ class HomeWidgetRepository {
if (localData.link.toString().isEmpty || if (localData.link.toString().isEmpty ||
localData.link.toString() == "null") { localData.link.toString() == "null") {
if (localData.type == null || localData.type!.isEmpty) { // ---------------- UUID short-circuit ----------------
// Content from the new content-service uses UUIDs (e.g. cdaa8830-).
// The legacy routes below assume int IDs, so for any UUID we route
// straight to InfographyDetails which knows how to fetch by UUID
// from content-service.
//
// Exception: trend / technology / startup intentionally render in
// their dedicated web apps (trend.didvan.app, tech.didvan.app,
// startup.didvan.app) for those types we fall through to the
// legacy switch below so the URL is constructed and opened in a
// WebView, even when the id is a UUID.
const _webViewTypes = {'trend', 'technology', 'startup'};
final _isWebViewType = _webViewTypes.contains(localData.type);
if (_isUuid(localData.id) && !_isWebViewType) {
if (kDebugMode) {
print("UUID detected — routing to InfographyDetails for "
"type='${localData.type}' id=${localData.id}");
}
route = Routes.infographyDetails;
args = {
'contentUuid': localData.id,
'link': localData.link,
};
} else if (localData.type == null || localData.type!.isEmpty) {
if (kDebugMode) { if (kDebugMode) {
print("=== NAVIGATION ABORTED ==="); print("=== NAVIGATION ABORTED ===");
print("Reason: Notification type is null or empty"); print("Reason: Notification type is null or empty");

View File

@ -219,43 +219,6 @@ class _InfographyDetailsState extends State<InfographyDetails> {
), ),
), ),
// === badge دستهبندی روی تصویر ===
if (_categoryLabel.isNotEmpty)
Positioned(
top: 16,
left: 16,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: const Color.fromARGB(255, 230, 242, 246),
borderRadius: BorderRadius.circular(16),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset(
_getCategoryIcon(_categoryLabel),
height: 16,
width: 16,
color:
const Color.fromARGB(255, 25, 93, 128),
),
const SizedBox(width: 6),
DidvanText(
_categoryLabel,
style: theme.textTheme.bodySmall?.copyWith(
color:
const Color.fromARGB(255, 25, 93, 128),
fontWeight: FontWeight.bold,
fontSize: 12,
),
),
],
),
),
),
// === کارت سفید روی تصویر، لبهی بالای آن «صاف» === // === کارت سفید روی تصویر، لبهی بالای آن «صاف» ===
Container( Container(
margin: EdgeInsets.only(top: imageHeight - overlap), margin: EdgeInsets.only(top: imageHeight - overlap),
@ -310,6 +273,48 @@ class _InfographyDetailsState extends State<InfographyDetails> {
), ),
), ),
// === badge دستهبندی (زیر تاریخ، بهجای روی عکس) ===
if (_categoryLabel.isNotEmpty)
Padding(
padding: const EdgeInsets.only(
left: 16, right: 16, top: 8),
child: Align(
alignment: AlignmentDirectional.centerStart,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: const Color.fromARGB(
255, 230, 242, 246),
borderRadius: BorderRadius.circular(16),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset(
_getCategoryIcon(_categoryLabel),
height: 16,
width: 16,
color: const Color.fromARGB(
255, 25, 93, 128),
),
const SizedBox(width: 6),
DidvanText(
_categoryLabel,
style: theme.textTheme.bodySmall
?.copyWith(
color: const Color.fromARGB(
255, 25, 93, 128),
fontWeight: FontWeight.bold,
fontSize: 12,
),
),
],
),
),
),
),
// خلاصه/توضیحات // خلاصه/توضیحات
if ((_description ?? '').isNotEmpty) ...[ if ((_description ?? '').isNotEmpty) ...[
const SizedBox(height: 16), const SizedBox(height: 16),