Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Add about page to Settings #1393

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a0abb3f
removed everything that wasnt about page
ydkmlt84 Oct 10, 2024
984f131
styling changes to about info
ydkmlt84 Oct 19, 2024
aa61b78
Merge branch 'jorenn92:main' into add-about-page
ydkmlt84 Oct 25, 2024
cb88437
basic outline of ideas
ydkmlt84 Oct 25, 2024
1b90ea7
added alternate about page idea
ydkmlt84 Oct 25, 2024
a90456f
adding releases to bottom of the about page (copied from overseerr)
ydkmlt84 Nov 16, 2024
eeadc41
Merge pull request #32 from jorenn92/main
ydkmlt84 Nov 16, 2024
17a3d24
Merge branch 'jorenn92:main' into add-about-page
ydkmlt84 Nov 20, 2024
9a1ddaa
removed stats about page
ydkmlt84 Nov 23, 2024
b3eafd6
Merge branch 'add-about-page' of https://github.com/ydkmlt84/Maintain…
ydkmlt84 Nov 23, 2024
021d926
Merge branch 'jorenn92:main' into add-about-page
ydkmlt84 Nov 23, 2024
24e8685
fixed releases modal and rule count
ydkmlt84 Nov 23, 2024
db5dd0b
added an about page.
ydkmlt84 Nov 23, 2024
6a67d1b
removing stray backtick and old testing page
ydkmlt84 Nov 23, 2024
9b237ea
fix: __PATH_PREFIX__ not replaced when using user directive (#1394)
benscobie Nov 25, 2024
126ac26
Add label tip for Base URL settings fields
jgillman Nov 20, 2024
20aa428
Merge pull request #1391 from jgillman/add-label-tip-for-base-url-fields
ydkmlt84 Nov 25, 2024
3ba6ee9
chore(deps-dev): bump @types/lodash from 4.17.7 to 4.17.13
dependabot[bot] Nov 25, 2024
f310547
Merge pull request #1397 from jorenn92/dependabot/npm_and_yarn/types/…
github-actions[bot] Nov 25, 2024
8ba25b4
chore(deps): bump @nestjs/common from 10.4.4 to 10.4.9
dependabot[bot] Nov 25, 2024
72a1e02
Merge pull request #1403 from jorenn92/dependabot/npm_and_yarn/nestjs…
github-actions[bot] Nov 25, 2024
0fc2ab0
chore(deps): bump @headlessui/react from 2.1.9 to 2.2.0
dependabot[bot] Nov 25, 2024
7ef19ad
Merge pull request #1399 from jorenn92/dependabot/npm_and_yarn/headle…
github-actions[bot] Nov 25, 2024
5d3879d
chore(deps-dev): bump @nestjs/testing from 10.4.7 to 10.4.9
dependabot[bot] Nov 25, 2024
aaec479
Merge pull request #1401 from jorenn92/dependabot/npm_and_yarn/nestjs…
github-actions[bot] Nov 25, 2024
79e0a1f
chore(deps): bump @types/node from 22.9.0 to 22.9.4
dependabot[bot] Nov 25, 2024
0646ba3
Merge pull request #1405 from jorenn92/dependabot/npm_and_yarn/types/…
github-actions[bot] Nov 25, 2024
1073709
chore(deps-dev): bump postcss from 8.4.47 to 8.4.49
dependabot[bot] Nov 25, 2024
7e9b3a0
Merge pull request #1398 from jorenn92/dependabot/npm_and_yarn/postcs…
github-actions[bot] Nov 25, 2024
5c63dd9
chore(deps): bump @nestjs/platform-express from 10.4.5 to 10.4.9
dependabot[bot] Nov 25, 2024
cca3b0f
Merge pull request #1400 from jorenn92/dependabot/npm_and_yarn/nestjs…
github-actions[bot] Nov 25, 2024
673bd51
removed everything that wasnt about page
ydkmlt84 Oct 10, 2024
1aadabb
styling changes to about info
ydkmlt84 Oct 19, 2024
22c05b5
basic outline of ideas
ydkmlt84 Oct 25, 2024
9ef6871
added alternate about page idea
ydkmlt84 Oct 25, 2024
e937d45
adding releases to bottom of the about page (copied from overseerr)
ydkmlt84 Nov 16, 2024
6e7dd66
trying to resolve yarn.lock conflicts
ydkmlt84 Nov 23, 2024
e65b6ea
fixed releases modal and rule count
ydkmlt84 Nov 23, 2024
cf3ff34
added an about page.
ydkmlt84 Nov 23, 2024
543d9bf
removing stray backtick and old testing page
ydkmlt84 Nov 23, 2024
5f2788e
Merge branch 'add-about-page' of https://github.com/ydkmlt84/Maintain…
ydkmlt84 Dec 2, 2024
4589dd7
Revert "Merge branch 'add-about-page' of https://github.com/ydkmlt84/…
ydkmlt84 Dec 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ RUN corepack install && \
# This is required for docker user directive to work
chmod 777 /opt && \
chmod 777 /opt/app/start.sh && \
chmod 777 -R /opt/app/ui && \
mkdir -m 777 /.cache && \
mkdir -pm 777 /opt/app/ui/.next/cache && \
chown -R node:node /opt/app/ui/.next/cache
Expand Down
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@
"migration:generate": "ts-node node_modules/typeorm/cli.js migration:generate --dataSource ./datasource-config.ts -p"
},
"dependencies": {
"@headlessui/react": "2.1.9",
"@headlessui/react": "2.2.0",
"@heroicons/react": "^1.0.6",
"@monaco-editor/react": "^4.6.0",
"@nestjs/cli": "^10.4.7",
"@nestjs/common": "^10.4.4",
"@nestjs/common": "^10.4.9",
"@nestjs/core": "^10.4.7",
"@nestjs/platform-express": "^10.4.5",
"@nestjs/platform-express": "^10.4.9",
"@nestjs/schedule": "^4.1.1",
"@nestjs/typeorm": "^10.0.2",
"@types/node": "^22.9.0",
"@types/node": "^22.9.4",
"axios": "^1.7.7",
"bowser": "^2.11.0",
"chalk": "^4.1.2",
Expand All @@ -56,6 +56,7 @@
"plex-api": "^5.3.2",
"react": "18.2.0",
"react-dom": "18.3.1",
"react-markdown": "^9.0.1",
"react-select": "^5.8.0",
"react-toast-notifications": "^2.5.1",
"react-transition-group": "^4.4.5",
Expand All @@ -77,7 +78,7 @@
"@eslint/js": "^9.13.0",
"@nestjs/cli": "^10.4.7",
"@nestjs/schematics": "^10.2.3",
"@nestjs/testing": "^10.4.7",
"@nestjs/testing": "^10.4.9",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/commit-analyzer": "^13.0.0",
"@semantic-release/exec": "^6.0.3",
Expand All @@ -88,7 +89,7 @@
"@tailwindcss/typography": "^0.5.15",
"@types/express": "^5.0.0",
"@types/jest": "^29.5.14",
"@types/lodash": "^4.17.7",
"@types/lodash": "^4.17.13",
"@types/react": "^18.2.73",
"@types/react-dom": "^18.3.0",
"@types/react-transition-group": "^4.4.11",
Expand All @@ -103,7 +104,7 @@
"eslint-plugin-prettier": "^5.2.1",
"jest": "^29.7.0",
"monaco-editor": "0.52.0",
"postcss": "^8.4.47",
"postcss": "^8.4.49",
"prettier": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.8",
"semantic-release": "^24.2.0",
Expand Down
168 changes: 168 additions & 0 deletions ui/src/components/Settings/About/Releases/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import Badge from '../../../Common/Badge'
import Button from '../../../Common/Button'
import LoadingSpinner from '../../../Common/LoadingSpinner'
import Modal from '../../../Common/Modal'
import dynamic from 'next/dynamic'
import { useEffect, useState } from 'react'

// Dynamic import for markdown
const ReactMarkdown = dynamic(() => import('react-markdown'), {
ssr: false,
})

const messages = {
releases: 'Releases',
releasedataMissing: 'Release data is currently unavailable.',
versionChangelog: '{version} Changelog',
viewongithub: 'View on GitHub',
latestversion: 'Latest',
currentversion: 'Current',
viewchangelog: 'View Changelog',
close: 'Close',
}

const REPO_RELEASE_API =
'https://api.github.com/repos/jorenn92/maintainerr/releases?per_page=10'

interface GitHubRelease {
url: string
assets_url: string
upload_url: string
html_url: string
id: number
node_id: string
tag_name: string
target_commitish: string
name: string
draft: boolean
prerelease: boolean
created_at: string
published_at: string
tarball_url: string
zipball_url: string
body: string
}
interface ReleaseProps {
release: GitHubRelease
isLatest: boolean
currentVersion: string
}
interface ModalProps {
title: string
children: React.ReactNode
isOpen: boolean
onCancel: () => void
onOk?: () => void
cancelText?: string
okText?: string
}

const calculateRelativeTime = (dateString: string): string => {
const secondsAgo = Math.floor(
(Date.now() - new Date(dateString).getTime()) / 1000,
)
const minutesAgo = Math.floor(secondsAgo / 60)
const hoursAgo = Math.floor(minutesAgo / 60)
const daysAgo = Math.floor(hoursAgo / 24)

if (secondsAgo < 60) return `${secondsAgo} seconds ago`
if (minutesAgo < 60) return `${minutesAgo} minutes ago`
if (hoursAgo < 24) return `${hoursAgo} hours ago`
return `${daysAgo} days ago`
}

const Release = ({ currentVersion, release, isLatest }: ReleaseProps) => {
const [isModalOpen, setModalOpen] = useState(false)

return (
<div className="flex w-full flex-col space-y-3 rounded-md bg-zinc-700 px-4 py-2 shadow-md ring-1 ring-gray-700 sm:flex-row sm:space-y-0 sm:space-x-3">
{isModalOpen && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
<Modal
onCancel={() => setModalOpen(false)}
title={messages.versionChangelog.replace('{version}', release.name)}
cancelText={messages.close}
okText={messages.viewongithub}
onOk={() => {
window.open(release.html_url, '_blank')
}}
>
<div className="prose prose:sm">
<ReactMarkdown>{release.body}</ReactMarkdown>
</div>
</Modal>
</div>
)}
<div className="flex w-full flex-grow items-center justify-center space-x-2 truncate sm:justify-start">
<span className="truncate text-lg font-bold">
<span className="mr-2 whitespace-nowrap text-xs font-normal">
{calculateRelativeTime(release.created_at)}
</span>
{release.name}
</span>
{isLatest && (
<Badge badgeType="success">{messages.latestversion}</Badge>
)}
{release.name.includes(currentVersion) && (
<Badge badgeType="primary">{messages.currentversion}</Badge>
)}
</div>
<Button buttonType="primary" onClick={() => setModalOpen(true)}>
<span>{messages.viewchangelog}</span>
</Button>
</div>
)
}

interface ReleasesProps {
currentVersion: string
}

const Releases = ({ currentVersion }: ReleasesProps) => {
const [data, setData] = useState<GitHubRelease[] | null>(null)
const [error, setError] = useState<string | null>(null)

useEffect(() => {
const fetchReleases = async () => {
try {
const response = await fetch(REPO_RELEASE_API)
if (!response.ok) {
throw new Error(`Error: ${response.status}`)
}
const releases = await response.json()
setData(releases)
} catch (err) {
setError(err.message || 'Failed to fetch releases')
}
}

fetchReleases()
}, [])

if (!data && !error) {
return <LoadingSpinner />
}

if (error) {
return <div className="text-gray-300">{messages.releasedataMissing}</div>
}

return (
<div>
<h3 className="heading">{messages.releases}</h3>
<div className="section space-y-3">
{data?.map((release, index) => (
<div key={`release-${release.id}`}>
<Release
release={release}
currentVersion={currentVersion}
isLatest={index === 0}
/>
</div>
))}
</div>
</div>
)
}

export default Releases
Loading
Loading