From b07790ea6bffdcc08a8bea6235f7d5794bddb5a8 Mon Sep 17 00:00:00 2001 From: Raunak Raj <71929976+bajrangCoder@users.noreply.github.com> Date: Sun, 10 Aug 2025 19:56:18 +0530 Subject: [PATCH 1/3] feat: add package updated time display to plugin page - Add package_updated_at to plugin view - Display relative time (5h ago, 2d ago, etc.) next to version number --- src/pages/plugin/plugin.scss | 45 ++++++++++++++++---- src/pages/plugin/plugin.view.js | 74 +++++++++++++++++++++++++++++++-- 2 files changed, 107 insertions(+), 12 deletions(-) diff --git a/src/pages/plugin/plugin.scss b/src/pages/plugin/plugin.scss index 6c69e6042..155ec5921 100644 --- a/src/pages/plugin/plugin.scss +++ b/src/pages/plugin/plugin.scss @@ -12,6 +12,7 @@ gap: 20px; align-items: start; margin-bottom: 24px; + .plugin-icon { width: 80px; height: 80px; @@ -20,6 +21,7 @@ background-repeat: no-repeat; background-size: contain; } + .plugin-info { .title-wrapper { display: flex; @@ -27,10 +29,12 @@ flex-wrap: wrap; gap: 16px; margin-bottom: 8px; + .plugin-name { font-size: 24px; margin-bottom: 0; } + .source-indicator { display: flex; align-items: center; @@ -45,16 +49,19 @@ transition: all 0.3s ease; border: 1px solid rgba(255, 255, 255, 0.1); text-decoration: none; + &:hover { background-color: rgba(0, 0, 0, 0.5); transform: translateY(-1px); } + .icon { color: var(--primary-text-color); font-size: 14px; } } } + .plugin-meta { display: flex; gap: 16px; @@ -62,19 +69,28 @@ color: color-mix(in srgb, var(--primary-text-color) 60%, transparent); font-size: 14px; margin-bottom: 12px; + .author-name { display: inline-flex; align-items: center; gap: 4px; + a { text-decoration: none; color: inherit; } } + .verified-tick { color: #3b82f6; font-size: 16px; } + + .version-updated { + opacity: 0.6; + font-size: 0.8em; + margin-left: 4px; + } } .metrics-row { @@ -88,10 +104,12 @@ display: flex; align-items: center; gap: 4px; + .metric-value { color: var(--primary-text-color); font-weight: 500; } + .rating-value { padding: 2px 8px; border-radius: 12px; @@ -114,6 +132,7 @@ } } } + .keywords { display: flex; gap: 6px; @@ -122,21 +141,19 @@ position: relative; .keyword { - background: color-mix( - in srgb, - var(--link-text-color) 10%, - transparent - ); + background: color-mix(in srgb, + var(--link-text-color) 10%, + transparent); color: var(--link-text-color); padding: 6px 10px; border-radius: 12px; font-size: 13px; transition: all 0.2s; - border: 1px solid - color-mix(in srgb, var(--link-text-color) 25%, transparent); + border: 1px solid color-mix(in srgb, var(--link-text-color) 25%, transparent); } } } + .action-buttons { display: flex; gap: 8px; @@ -164,10 +181,12 @@ display: inline-flex; align-items: center; gap: 6px; + &:hover { transform: translateY(-1px); } } + .btn-install { background: var(--button-background-color); color: white; @@ -182,12 +201,14 @@ background-color: var(--danger-color) !important; color: white; } + .btn-secondary { background: var(--primary-color); color: var(--primary-text-color); - shadow: 0 0 10px var(--box-shadow-color); + box-shadow: 0 0 10px var(--box-shadow-color); } } + .more-info-small { text-align: center; font-style: italic; @@ -231,6 +252,7 @@ width: calc(100% - 10px); display: block; user-select: text; + div { background: var(--primary-color); } @@ -279,17 +301,20 @@ } } } + #changelog { .no-changelog { text-align: center; padding: 2rem; color: color-mix(in srgb, var(--primary-text-color) 60%, transparent); + i { font-size: 3rem; margin-bottom: 1rem; opacity: 0.7; display: block; } + p { margin: 0.5rem 0; } @@ -309,6 +334,7 @@ top: 20px; right: 20px; } + .title-wrapper, .plugin-meta, .metrics-row, @@ -333,6 +359,7 @@ } } } + .reviews-container { position: fixed; display: flex; @@ -450,4 +477,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/pages/plugin/plugin.view.js b/src/pages/plugin/plugin.view.js index 9544272c9..4833f83e0 100644 --- a/src/pages/plugin/plugin.view.js +++ b/src/pages/plugin/plugin.view.js @@ -27,6 +27,7 @@ export default (props) => { author_verified: authorVerified, author_github: authorGithub, comment_count: commentCount, + package_updated_at: packageUpdatedAt, } = props; let rating = "unrated"; @@ -42,6 +43,48 @@ export default (props) => { rating = `${Math.round((votesUp / (votesUp + votesDown)) * 100)}%`; } + const formatUpdatedDate = (dateString) => { + if (!dateString) return null; + + const date = new Date(dateString); + const now = new Date(); + const diffTime = now - date; + + if (diffTime < 0) return null; + + const diffSeconds = Math.floor(diffTime / 1000); + const diffMinutes = Math.floor(diffSeconds / 60); + const diffHours = Math.floor(diffMinutes / 60); + const diffDays = Math.floor(diffHours / 24); + const diffWeeks = Math.floor(diffDays / 7); + const diffMonths = Math.floor(diffDays / 30); + const diffYears = Math.floor(diffDays / 365); + + if (diffSeconds < 60) { + return "just now"; + } else if (diffMinutes < 60) { + return `${diffMinutes}m ago`; + } else if (diffHours < 24) { + return `${diffHours}h ago`; + } else if (diffDays === 1) { + return "yesterday"; + } else if (diffDays < 7) { + return `${diffDays}d ago`; + } else if (diffWeeks === 1) { + return "1w ago"; + } else if (diffDays < 30) { + return `${diffWeeks}w ago`; + } else if (diffMonths === 1) { + return "1mo ago"; + } else if (diffDays < 365) { + return `${diffMonths}mo ago`; + } else if (diffYears === 1) { + return "1y ago"; + } else { + return `${diffYears}y ago`; + } + }; + return (