diff --git a/package-lock.json b/package-lock.json index 7e5bf9637..584c27f7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,12 @@ { "name": "com.foxdebug.acode", - - "version": "1.11.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "com.foxdebug.acode", - "version": "1.11.5", - "license": "MIT", "dependencies": { "@deadlyjack/ajax": "^1.2.6", @@ -41,6 +37,7 @@ "markdown-it-task-lists": "^2.1.1", "mime-types": "^2.1.35", "minimatch": "^9.0.4", + "moment": "^2.30.1", "mustache": "^4.2.0", "url-parse": "^1.5.10", "vanilla-picker": "^2.12.3", @@ -7703,6 +7700,15 @@ "node": ">=10" } }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.2", "license": "MIT" diff --git a/package.json b/package.json index 69806ce9c..a609c5ab0 100644 --- a/package.json +++ b/package.json @@ -123,10 +123,11 @@ "markdown-it-task-lists": "^2.1.1", "mime-types": "^2.1.35", "minimatch": "^9.0.4", + "moment": "^2.30.1", "mustache": "^4.2.0", "url-parse": "^1.5.10", "vanilla-picker": "^2.12.3", "yargs": "^17.7.2" }, "browserslist": "cover 100%,not android < 5" -} \ No newline at end of file +} 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..b502db30f 100644 --- a/src/pages/plugin/plugin.view.js +++ b/src/pages/plugin/plugin.view.js @@ -6,6 +6,7 @@ import DOMPurify from "dompurify"; import Ref from "html-tag-js/ref"; import actionStack from "lib/actionStack"; import constants from "lib/constants"; +import moment from "moment"; import helpers from "utils/helpers"; import Url from "utils/Url"; @@ -27,6 +28,7 @@ export default (props) => { author_verified: authorVerified, author_github: authorGithub, comment_count: commentCount, + package_updated_at: packageUpdatedAt, } = props; let rating = "unrated"; @@ -42,6 +44,40 @@ export default (props) => { rating = `${Math.round((votesUp / (votesUp + votesDown)) * 100)}%`; } + const formatUpdatedDate = (dateString) => { + if (!dateString) return null; + + try { + // Configure moment for shorter relative time format + moment.updateLocale("en", { + relativeTime: { + future: "in %s", + past: "%s ago", + s: "now", + ss: "now", + m: "1m", + mm: "%dm", + h: "1h", + hh: "%dh", + d: "1d", + dd: "%dd", + M: "1mo", + MM: "%dmo", + y: "1y", + yy: "%dy", + }, + }); + + const updateTime = moment.utc(dateString); + if (!updateTime.isValid()) return null; + + return updateTime.fromNow(); + } catch (error) { + console.warn("Error parsing date with moment:", dateString, error); + return null; + } + }; + return (
@@ -62,7 +98,11 @@ export default (props) => {
- + @@ -307,11 +347,32 @@ function Buttons({ ); } -function Version({ currentVersion, version }) { - if (!currentVersion) return v{version}; +function Version({ + currentVersion, + version, + packageUpdatedAt, + formatUpdatedDate, +}) { + const updatedText = + formatUpdatedDate && packageUpdatedAt + ? formatUpdatedDate(packageUpdatedAt) + : null; + + if (!currentVersion) { + return ( + + v{version} + {updatedText && ( + ({updatedText}) + )} + + ); + } + return ( v{currentVersion} → v{version} + {updatedText && ({updatedText})} ); } diff --git a/www/index.html b/www/index.html index 8e9d2b728..6cab48cb1 100644 --- a/www/index.html +++ b/www/index.html @@ -165,11 +165,11 @@ Acode - - - - - + + + + +