Add readme to app page
Refactor downloads/latest release
This commit is contained in:
Родитель
f879261bc0
Коммит
2fe220e484
2724
data/apps.json
2724
data/apps.json
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -4,6 +4,38 @@
|
|||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||
|
||||
<meta content='#2f3241' name='theme-color' />
|
||||
{{#if pageDetails}}
|
||||
<meta property="og:type" content="website" />
|
||||
{{#if pageDetails.url}}
|
||||
<meta property="og:url" content="{{pageDetails.url}}" />
|
||||
{{/if}}
|
||||
{{#if pageDetails.title}}
|
||||
<title>{{pageDetails.title}}</title>
|
||||
<meta property="og:title" content="{{pageDetails.title}}" />
|
||||
{{/if}}
|
||||
{{#if pageDetails.description}}
|
||||
<meta property="og:description" content="{{pageDetails.description}}" />
|
||||
{{/if}}
|
||||
{{#if pageDetails.image}}
|
||||
<meta property="og:image" content="{{pageDetails.image}}" />
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
{{else}}
|
||||
<meta name="twitter:card" content="summary">
|
||||
{{/if}}
|
||||
{{#if pageDetails.title}}
|
||||
<meta name="twitter:title" value="{{pageDetails.title}}" />
|
||||
{{/if}}
|
||||
{{#if pageDetails.description}}
|
||||
<meta name="twitter:description" value="{{pageDetails.description}}" />
|
||||
{{/if}}
|
||||
{{#if pageDetails.image}}
|
||||
<meta property="twitter:image" content="{{pageDetails.image}}" />
|
||||
{{/if}}
|
||||
{{#if pageDetails.url}}
|
||||
<meta name="twitter:url" value="{{pageDetails.url}}" />
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
<meta name="twitter:site" content="@ElectronJS" />
|
||||
<link rel='shortcut icon' href='/images/favicon.ico'/>
|
||||
<link rel='stylesheet' href='/css/index.css'>
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
// App page ------------------------------
|
||||
.app-readme {
|
||||
.octicon-link {
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -76,6 +76,7 @@ $octicons-font-path: "../bower_components/octicons/octicons/";
|
|||
@import "basecoat-tables";
|
||||
|
||||
// Pages
|
||||
@import "app";
|
||||
@import "home";
|
||||
@import "hero";
|
||||
@import "docs";
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
const electronApps = require('electron-apps')
|
||||
const cheerio = require('cheerio')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const categories = []
|
||||
const downloadExtensions = [
|
||||
'.deb',
|
||||
'.dmg',
|
||||
'.exe',
|
||||
'.gz',
|
||||
'.zip'
|
||||
]
|
||||
|
||||
electronApps.forEach((app) => {
|
||||
let appCategory = categories.find((category) => {
|
||||
|
@ -26,29 +20,22 @@ electronApps.forEach((app) => {
|
|||
appCategory.count++
|
||||
}
|
||||
app.categorySlug = appCategory.slug
|
||||
if (app.releases.length > 0) {
|
||||
let latestRelease = app.releases.find((release) => {
|
||||
return (!release.draft && !release.prerelease)
|
||||
if (app.readme) {
|
||||
let $ = cheerio.load(app.readme)
|
||||
let updateReadme
|
||||
$('img').each(function (i, img) {
|
||||
let currentImg = $(img)
|
||||
let imageSrc = currentImg.attr('src')
|
||||
if (imageSrc && imageSrc.indexOf('http') === -1) {
|
||||
currentImg.attr('src', `${app.repository}/raw/master/${imageSrc}`)
|
||||
updateReadme = true
|
||||
}
|
||||
})
|
||||
if (latestRelease) {
|
||||
app.latestRelease = Object.assign({
|
||||
releaseUrl: latestRelease.html_url,
|
||||
tagName: latestRelease.tag_name,
|
||||
releaseName: latestRelease.name,
|
||||
releaseNotes: latestRelease.body
|
||||
})
|
||||
app.latestRelease.downloads = latestRelease.assets.filter((asset) => {
|
||||
let fileExtension = path.extname(asset.browser_download_url)
|
||||
return (downloadExtensions.indexOf(fileExtension) !== -1)
|
||||
}).map((asset) => {
|
||||
return Object.assign({
|
||||
fileName: asset.name,
|
||||
fileUrl: asset.browser_download_url
|
||||
})
|
||||
})
|
||||
if (updateReadme) {
|
||||
console.log(`Updating readme for ${app.name}`)
|
||||
app.readme = $('body').html()
|
||||
}
|
||||
}
|
||||
delete app.releases
|
||||
})
|
||||
|
||||
categories.sort((a, b) => {
|
||||
|
|
23
server.js
23
server.js
|
@ -11,7 +11,7 @@ const helmet = require('helmet')
|
|||
const port = Number(process.env.PORT) || argv.p || argv.port || 5000
|
||||
const app = express()
|
||||
const jexodus = require('./lib/jexodus')(__dirname).on('ready', startServer)
|
||||
const md = require('markdown-it')()
|
||||
const host = process.env.HOST || `http://localhost:${port}`
|
||||
|
||||
app.engine('html', hbs.express4({
|
||||
defaultLayout: path.join(__dirname, '/views/layouts/main.html'),
|
||||
|
@ -24,10 +24,6 @@ app.engine('html', hbs.express4({
|
|||
}
|
||||
}))
|
||||
|
||||
hbs.registerHelper('mdtohtml', function (markdown) {
|
||||
return md.render(markdown)
|
||||
})
|
||||
|
||||
app.set('view engine', 'html')
|
||||
app.set('views', path.join(__dirname, '/views'))
|
||||
app.use(helmet())
|
||||
|
@ -68,6 +64,11 @@ app.get('/apps', (req, res) => {
|
|||
})
|
||||
|
||||
appList.appLength = electronApps.apps.length
|
||||
appList.pageDetails = {
|
||||
title: 'Electron | Apps',
|
||||
url: req.url,
|
||||
description: 'Apps Built on Electron'
|
||||
}
|
||||
res.render('apps', appList)
|
||||
})
|
||||
|
||||
|
@ -78,7 +79,17 @@ app.get('/app/:slug', (req, res) => {
|
|||
app.get('/apps/:slug', (req, res) => {
|
||||
const app = electronApps.apps.find(app => app.slug === req.params.slug)
|
||||
const context = {
|
||||
app: app
|
||||
app: app,
|
||||
pageDetails: {
|
||||
title: `Electron | Apps | ${app.name}`,
|
||||
url: req.url,
|
||||
description: app.description
|
||||
}
|
||||
}
|
||||
if (app.screenshots && app.screenshots.length > 0) {
|
||||
context.pageDetails.image = app.screenshots[0].imageUrl
|
||||
} else {
|
||||
context.pageDetails.image = `${host}/images/apps/${app.icon64}`
|
||||
}
|
||||
res.render('app', context)
|
||||
})
|
||||
|
|
|
@ -7,17 +7,25 @@
|
|||
</ol>
|
||||
</nav>
|
||||
<div class="container-narrow media-fluid">
|
||||
<h1><a href="{{app.website}}">{{app.name}}</a></h1>
|
||||
<h1>
|
||||
<a href="{{app.website}}">
|
||||
<div class='listed-app-logo-wrapper'>
|
||||
<img class='listed-app-logo' src='/images/apps/{{app.icon64}}' alt='{{app.name}}'>
|
||||
</div>
|
||||
{{app.name}}
|
||||
</a>
|
||||
</h1>
|
||||
<h3>
|
||||
{{app.description}}
|
||||
</h3>
|
||||
|
||||
<h3>{{app.description}}</h3>
|
||||
{{#each app.screenshots}}
|
||||
<h4 class="app-caption text-center">App Screenshot</h4>
|
||||
<a href="{{../app.website}}">
|
||||
<img src="{{imageUrl}}"></img>
|
||||
</a>
|
||||
|
||||
{{#if app.screenshots}}
|
||||
{{#each app.screenshots}}
|
||||
<img src="{{this.imageUrl}}"></img>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<h4>No screenshots available</h4>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
|
||||
<div>
|
||||
<strong>Category</strong> <a href="/apps?category={{app.categorySlug}}">{{app.category}}</a>
|
||||
|
@ -39,7 +47,7 @@
|
|||
<div>
|
||||
<strong>Keywords</strong>
|
||||
{{#each app.keywords}}
|
||||
{{this}}
|
||||
<a href="/apps?q={{this}}">{{this}}</a>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
@ -53,22 +61,55 @@
|
|||
</div>
|
||||
{{/if}}
|
||||
{{#if app.latestRelease}}
|
||||
<div><strong>Latest Release</strong></div>
|
||||
<h5 class="px-2"><a href="{{app.latestRelease.releaseUrl}}">{{app.latestRelease.releaseName}} | <span class="octicon octicon-tag mr-1"></span> {{app.latestRelease.tagName}}</a></h5>
|
||||
{{#if app.latestRelease.downloads}}
|
||||
<h5 class="px-2">Downloads</h5>
|
||||
<div class="row px-2">
|
||||
<div>
|
||||
<strong>
|
||||
Downloads (<a href="{{app.latestRelease.releaseUrl}}">
|
||||
{{app.latestRelease.releaseName}} | <span class="octicon octicon-tag mr-1">
|
||||
</span> {{app.latestRelease.tagName}}</a>)
|
||||
</strong>
|
||||
{{#each app.latestRelease.downloads}}
|
||||
<h5 class="col-xs-3"><a href="{{this.fileUrl}}">{{this.fileName}}</a></h5>
|
||||
<a href="{{this.fileUrl}}">{{this.fileName}}</a>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<h5 class="px-2">Notes</h5>
|
||||
<div class="row px-2">
|
||||
<div class="col-xs-12">
|
||||
{{{mdtohtml app.latestRelease.releaseNotes}}}
|
||||
{{else}}
|
||||
<div>
|
||||
<strong>Latest Release Notes (<a href="{{app.latestRelease.releaseUrl}}">
|
||||
{{app.latestRelease.releaseName}} | <span class="octicon octicon-tag mr-1">
|
||||
</span> {{app.latestRelease.tagName}}</a>)
|
||||
</strong>
|
||||
</div>
|
||||
<div class="row px-2">
|
||||
<div class="col-xs-12">
|
||||
{{{app.latestRelease.releaseNotes}}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if app.readme}}
|
||||
<div>
|
||||
<button class="btn btn-link" type="button" id="display-readme">
|
||||
<strong>More Details</strong> <span id="display-readme-icon" class="octicon octicon-triangle-up"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="readme" class="app-readme d-none">
|
||||
{{{app.readme}}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
document.getElementById('display-readme').addEventListener('click', function(event) {
|
||||
var readme = document.getElementById('readme')
|
||||
var readmeIcon = document.getElementById('display-readme-icon')
|
||||
if (readme.className === 'app-readme d-none') {
|
||||
readme.className = 'app-readme'
|
||||
readmeIcon.className = 'octicon octicon-triangle-down'
|
||||
} else {
|
||||
readmeIcon.className = 'octicon octicon-triangle-up'
|
||||
readme.className = 'app-readme d-none'
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
Загрузка…
Ссылка в новой задаче