Clean up old Nuxt and Eleventy files

This commit is contained in:
Sam Carlton 2022-07-02 15:05:14 -05:00
parent 7b0aaeb413
commit f33d2f4099
33 changed files with 0 additions and 4032 deletions

View file

@ -1,6 +0,0 @@
# PAGES
This directory contains your Application Views and Routes.
The framework reads all the `*.vue` files inside this directory and create the router of your application.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).

View file

@ -1,268 +0,0 @@
<template>
<section class="container pb-16">
<div class="flex flex-col items-center text-center space-y-8">
<template
v-if="video"
>
<VideoPlayer
:video="video"
class="pt-16"
/>
<ChannelCredit
:video="video"
class="flex w-full justify-start md:px-10"
/>
</template>
<template v-else>
<div
:style="{
'left': '50%',
'right': '50%',
'margin-left': '-50vw',
'margin-right': '-50vw'
}"
class="video-canvas w-screen flex justify-center bg-black pt-16"
>
<div class="ratio-wrapper w-full max-w-4xl">
<div class="relative overflow-hidden w-full pb-16/9">
<div class="absolute h-full w-full flex justify-center items-center">
<div class="message text-4xl md:text-6xl font-hairline leading-tight text-center">No videos yet</div>
</div>
</div>
</div>
</div>
</template>
<!-- <h1 class="title text-sm md:text-3xl font-bold">
{{ video.name }}
</h1> -->
<div class="related-videos w-full max-w-4xl">
<h2 class="subtitle text-xl md:text-2xl font-bold mb-3">
Benchmark Videos
</h2>
<!-- <pre class="text-left">{{ benchmarkVideos }}</pre> -->
<VideoRow
:videos="benchmarkVideos"
:active-video-id="activeVideoId"
/>
</div>
<div
v-if="performanceVideos.length !== 0"
class="performance-videos w-full max-w-4xl"
>
<h2 class="subtitle text-xl md:text-2xl font-bold mb-3">
Performance Videos
</h2>
<!-- <pre class="text-left">{{ performanceVideos }}</pre> -->
<VideoRow
:videos="performanceVideos"
:active-video-id="activeVideoId"
/>
</div>
<div
v-if="moreVideos.length !== 0"
class="related-videos w-full max-w-4xl"
>
<h2 class="subtitle text-xl md:text-2xl font-bold mb-3">
More Videos
</h2>
<!-- <pre class="text-left">{{ relatedVideos }}</pre> -->
<VideoRow
:videos="moreVideos"
:active-video-id="activeVideoId"
/>
</div>
<!-- video: {{ video }} -->
<!-- <div class="links space-y-6 sm:space-x-6 mb-8">
<LinkButton
v-for="(link, i) in app.relatedLinks"
:key="i"
:href="link.href"
target="_blank"
class=""
>{{ (i === 0) ? 'View' : link.label }}</LinkButton>
</div> -->
</div>
</section>
</template>
<script>
import LinkButton from '~/components/link-button.vue'
import EmailSubscribe from '~/components/email-subscribe.vue'
import VideoRow from '~/components/video/row.vue'
import VideoPlayer from '~/components/video/player.vue'
import ChannelCredit from '~/components/video/channel-credit.vue'
export default {
components: {
LinkButton,
EmailSubscribe,
VideoRow,
VideoPlayer,
ChannelCredit
},
async asyncData ( data ) {
const {
params: { slug },
route
} = data
let {
payload
} = data
// Manually get payload as fallback
// Uncomment for dev
// if ( payload === undefined ) {
// // Read back the JSON we just wrote to ensure it exists
// const { default: savedList } = await import('~/static/nuxt-endpoints.json')
// const endpoint = savedList.find( resource => {
// return resource.route === route.path
// } )
// payload = endpoint.payload
// }
return {
app: payload.app,
allVideos: payload.allVideos,
submitVideoCard: payload.submitVideoCard
}
},
data: function () {
return {
activeVideoIndex: 0,
benchmarkVideos: [],
performanceVideos: [],
moreVideos: [],
}
},
computed: {
video () {
return this.allVideos[this.activeVideoIndex]
},
title () {
return `${this.app.name} Benchmarks for Apple Silicon - Does It ARM`
},
description () {
return `Apple Silicon benchmark, performance, and support videos for ${this.app.name}`
},
activeVideoId () {
return (this.video === Object(this.video)) ? this.video.id : null
}
},
created () {
const nonBenchmarkVideos = []
// console.log('benchmarkVideos.length', this.benchmarkVideos.length)
// console.log('performanceVideos.length', this.performanceVideos.length)
// console.log('moreVideos.length', this.moreVideos.length)
// Move benchmark videos out of related videos
this.allVideos.forEach((video, index) => {
// console.log('video.name', video.name)
// console.log('video.tags', video.tags)
if (!video.tags.includes('benchmark')) {
nonBenchmarkVideos.push(video)
return
}
// Add to benchmark videos
this.benchmarkVideos.push(video)
})
// console.log('Added benchmark videos')
// console.log('benchmarkVideos.length', this.benchmarkVideos.length)
// console.log('performanceVideos.length', this.performanceVideos.length)
// console.log('moreVideos.length', this.moreVideos.length)
// Move performance videos out of related videos
nonBenchmarkVideos.forEach((video, index) => {
if (!video.tags.includes('performance')) {
this.moreVideos.push(video)
return
}
// Add to benchmark videos
this.performanceVideos.push(video)
})
// Append submit card to end
this.benchmarkVideos.push(this.submitVideoCard)
// console.log('Added performance videos')
// console.log('benchmarkVideos.length', this.benchmarkVideos.length)
// console.log('performanceVideos.length', this.performanceVideos.length)
// console.log('moreVideos.length', this.moreVideos.length)
},
mounted () {
window.onhashchange = this.loadVideoFromHash
if (location.hash.length !== 0) this.loadVideoFromHash()
},
methods: {
loadVideoFromHash () {
// console.log('location.hash', location.hash)
// Separate the video id from our window hash
const hashId = location.hash.split('#')[1]
// Find the index of the video with the matching hash
const newVideoIndex = this.allVideos.findIndex(video => {
return video.id === hashId
})
console.log('newVideoIndex', newVideoIndex)
// Load in the index to load out video
this.activeVideoIndex = newVideoIndex
window.scroll({ top: 0, behavior: 'smooth' })
}
},
head() {
return {
title: this.title,
meta: [
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
{
'hid': 'description',
'name': 'description',
'content': this.description
},
// Twitter Card
{
'hid': 'twitter:title',
'property': 'twitter:title',
'content': this.title
},
{
'hid': 'twitter:description',
'property': 'twitter:description',
'content': this.description
},
{
'property': 'twitter:url',
'content': `${process.env.URL}${this.$nuxt.$route.path}`
},
]
}
}
}
</script>

View file

@ -1,141 +0,0 @@
<template>
<section class="container py-32">
<div class="flex flex-col items-center text-center space-y-8">
<div class="hero-heading space-y-6">
<h1 class="title text-sm md:text-2xl font-bold">
Does {{ app.name }} work on Apple Silicon?
</h1>
<h2 class="subtitle text-2xl md:text-5xl font-bold">
{{ app.text }}
</h2>
</div>
<div class="subscribe">
<AllUpdatesSubscribe
:app-name="app.name"
/>
</div>
<div class="links space-y-6 sm:space-x-6">
<LinkButton
v-for="(link, i) in app.relatedLinks"
:key="i"
:href="link.href"
target="_blank"
class=""
>{{ (i === 0) ? 'View' : link.label }}</LinkButton>
</div>
<div
v-if="relatedVideos.length !== 0"
class="related-videos w-full"
>
<h2 class="subtitle text-xl md:text-2xl font-bold mb-3">
Related Videos
</h2>
<VideoRow
:videos="relatedVideos"
/>
</div>
<div class="report-links py-24 text-xs shadow-none">
<div v-if="app.lastUpdated">
<time
:datetime="app.lastUpdated.raw"
>
Last Updated {{ lastUpdatedFriendly }}
</time>
</div>
<!-- https://eric.blog/2016/01/08/prefilling-github-issues/ -->
<a
:href="`https://github.com/ThatGuySam/doesitarm/issues?q=is%3Aissue+is%3Aopen+${app.name}`"
target="_blank"
class="underline"
rel="noopener"
>Report Update</a>
</div>
</div>
</section>
</template>
<script>
import { makeLastUpdatedFriendly } from '~/helpers/parse-date'
import { getAppEndpoint } from '~/helpers/app-derived.js'
import LinkButton from '~/components/link-button.vue'
import AllUpdatesSubscribe from '~/components/all-updates-subscribe.vue'
import VideoRow from '~/components/video/row.vue'
import appList from '~/static/app-list.json'
// import buildAppList from '~/helpers/build-app-list'
export default {
components: {
LinkButton,
AllUpdatesSubscribe,
VideoRow
},
async asyncData ({ params: { slug } }) {
const { default: videoList } = await import('~/static/video-list.json')
const { videosRelatedToApp } = await import('~/helpers/related.js')
const app = appList.find(app => (app.slug === slug))
const relatedVideos = videosRelatedToApp( app, (new Set(videoList)) )
// Find other videos that also feature this video's app
// for (const video of videoList) {
// if (!video.apps.includes(app.slug)) continue
// relatedVideos.push(video)
// }
return {
slug,
app,
relatedVideos: relatedVideos.map(video => {
// console.log('video', video)
return {
...video,
endpoint: `${getAppEndpoint(app)}/benchmarks#${video.id}`
}
})
}
},
computed: {
lastUpdatedFriendly () {
return makeLastUpdatedFriendly( this.app.lastUpdated )
}
},
head() {
return {
title: `Does ${this.app.name} work on Apple Silicon?`,
meta: [
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
{
'hid': 'description',
'name': 'description',
'content': `Check the the latest reported support status of ${this.app.name} on Apple Silicon and ${ process.env.npm_package_config_verbiage_processors } Processors`
},
// Twitter Card
{
'hid': 'twitter:title',
'property': 'twitter:title',
'content': `Does ${this.app.name} work on Apple Silicon?`
},
{
'hid': 'twitter:description',
'property': 'twitter:description',
'content': `Check the the latest reported support status of ${this.app.name} on Apple Silicon and ${ process.env.npm_package_config_verbiage_processors } Processors`
},
{
'property': 'twitter:url',
'content': `${process.env.URL}${this.$nuxt.$route.path}`
},
]
}
}
}
</script>

View file

@ -1,253 +0,0 @@
<template>
<section class="container relative md:static overflow-hidden md:overflow-visible pb-16">
<div class="flex flex-col items-center text-center space-y-12">
<BgPlayer
:video="video"
class="absolute overflow-hidden w-2x-screen md:w-full pointer-events-none"
/>
<div class="page-heading flex justify-start w-full">
<h1 class="title text-2xl leading-tight mt-12 mb-6">
Benchmarks
</h1>
</div>
<div class="line-separator border-white border-t-2 mb-12" />
<a
:href="video.endpoint"
>
<div
class="relative flex flex-col w-full justify-center items-center space-y-8 py-16 md:pt-0 md:pb-12 md:px-10"
>
<div
class="play-circle w-16 h-16 bg-white-2 bg-blur flex justify-center items-center outline-0 rounded-full ease"
>
<svg
viewBox="0 0 18 18"
style="width:24px;height:24px;margin-left:3px"
>
<path
fill="currentColor"
d="M15.562 8.1L3.87.225c-.818-.562-1.87 0-1.87.9v15.75c0 .9 1.052 1.462 1.87.9L15.563 9.9c.584-.45.584-1.35 0-1.8z"
/>
</svg>
</div>
<h2 class="title text-lg md:text-2xl font-bold">
{{ video.name }}
</h2>
</div>
</a>
<div
class="features-apps w-full"
>
<hr class="w-full" >
<div class="featured-apps overflow-x-auto overflow-y-visible whitespace-no-wrap py-2 space-x-2">
<LinkButton
v-for="app in featuredApps"
:key="app.slug"
:href="app.endpoint"
:class="[
'inline-block text-xs rounded-lg py-1 px-2',
]"
:class-groups="{
shadow: 'neumorphic-shadow-inner'
}"
>{{ app.name }}</LinkButton>
</div>
</div>
<div
v-for="(row, key) in videoRows"
:key="key"
:class="`${key}-videos w-full max-w-4xl`"
>
<h2 class="subtitle text-xl md:text-2xl font-bold mb-3">
{{ row.heading }}
</h2>
<!-- <pre class="text-left">{{ benchmarkVideos }}</pre> -->
<VideoRow
:videos="row.videos"
/>
</div>
</div>
</section>
</template>
<script>
import { getVideoEndpoint, getAppEndpoint } from '~/helpers/app-derived.js'
import LinkButton from '~/components/link-button.vue'
import EmailSubscribe from '~/components/email-subscribe.vue'
import VideoRow from '~/components/video/row.vue'
import BgPlayer from '~/components/video/bg-player.vue'
import ChannelCredit from '~/components/video/channel-credit.vue'
export default {
components: {
LinkButton,
EmailSubscribe,
VideoRow,
BgPlayer,
ChannelCredit
},
async asyncData ({ params: { slug } }) {
const { appsRelatedToVideo } = await import('~/helpers/related.js')
const { default: videoList } = await import('~/static/video-list.json')
const { allVideoAppsList } = await import('~/helpers/get-list.js')
// Get featured apps
const featuredAppsSet = new Set()
videoList.slice(0, 24).forEach( video => {
appsRelatedToVideo(video, allVideoAppsList).forEach( app => {
featuredAppsSet.add(app)
})
})
return {
video: videoList[0],
featuredApps: Array.from(featuredAppsSet).map( app => {
return {
...app,
endpoint: getAppEndpoint(app) + '/benchmarks'
}
}),
allVideos: videoList.map( video => {
return {
...video,
endpoint: getVideoEndpoint(video)
}
})
}
},
data: function () {
return {
videoRows: {
'video-benchmarks': {
heading: 'Video Editing Benchmarks',
matchesCondition: video => {
return video.tags.includes('benchmark') && video.tags.includes('video-and-motion-tools')
},
videos: []
},
'music-and-audio-tools': {
heading: 'Music and DAW Performance',
matchesCondition: video => {
return video.tags.includes('music-and-audio-tools')
},
videos: []
},
// 'science-and-research-software': {
// heading: 'Science and Research',
// matchesCondition: video => {
// return video.tags.includes('science-and-research-software')
// },
// videos: []
// },
'photo-and-graphic-tools': {
heading: 'Photography and Design Compatibility',
matchesCondition: video => {
return video.tags.includes('photo-and-graphic-tools')
},
videos: []
},
'games': {
heading: 'Gaming Benchmarks',
matchesCondition: video => {
return video.tags.includes('benchmark') && video.tags.includes('games')
},
videos: []
},
'benchmarks': {
heading: 'Other Benchmark Videos',
matchesCondition: video => video.tags.includes('benchmark'),
videos: []
},
'performance': {
heading: 'Performance Videos',
matchesCondition: video => video.tags.includes('performance'),
videos: []
},
'other': {
heading: 'More Videos',
// Always true
matchesCondition: () => true,
videos: []
}
}
}
},
computed: {
title () {
return `Benchmarks for ${ process.env.npm_package_config_verbiage_processors } Processors and Apple Silicon - Does It ARM`
},
description () {
// const featuredAppsString = this.featuredApps.slice(0, 5).map(app => app.name).join(', ')
return `Apple Silicon benchmark, performance, and compatibility videos for Macs using the ${ process.env.npm_package_config_verbiage_processors } processors.`
},
activeVideoId () {
return this.video.id
}
},
created () {
// Move videos to relevant categories
this.allVideos.forEach((video, index) => {
// console.log('video.name', video.name)
// console.log('video.tags', video.tags)
// Look through row conditions to see if video matches
for (const row in this.videoRows) {
if( this.videoRows[row].matchesCondition(video) ) {
// Add the matching video
this.videoRows[row].videos.push(video)
return
}
}
})
// console.log('lengths', Object.values(this.videoRows).map(row => [row.heading, row.videos.length]))
},
head() {
return {
title: this.title,
meta: [
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
{
'hid': 'description',
'name': 'description',
'content': this.description
},
// Twitter Card
{
'hid': 'twitter:title',
'property': 'twitter:title',
'content': this.title
},
{
'hid': 'twitter:description',
'property': 'twitter:description',
'content': this.description
},
{
'property': 'twitter:url',
'content': `${process.env.URL}${this.$nuxt.$route.path}`
},
]
}
}
}
</script>

View file

@ -1,126 +0,0 @@
<template>
<section class="container py-24">
<div class="flex flex-col">
<h1 class="title text-2xl leading-tight mb-6">
Categories
</h1>
<div class="line-separator border-white border-t-2 mb-12" />
<!-- categoryList: {{ categoryList }} -->
<ul class="categories-list space-y-3">
<li
v-for="(category, i) in categoryList"
:key="`${category.slug}-${i}`"
:ref="`${category.slug}-row`"
class="relative"
>
<!-- category.endpoint: {{ category.endpoint }} -->
<a
:href="`/kind/${category.slug}`"
class="flex justify-start items-center inset-x-0 text-3xl md:text-4xl hover:bg-darkest border-2 border-white border-opacity-0 hover:border-opacity-50 focus:outline-none focus:bg-gray-50 duration-300 ease-in-out rounded-lg space-x-3 -mx-5 px-5 md:pr-64 py-3"
style="transition-property: border;"
>
<div class="font-hairline">
<div>{{ category.label }}</div>
<div class="text-xs opacity-75 mb-3">{{ category.appNames }}</div>
</div>
<div></div>
</a>
</li>
</ul>
</div>
</section>
</template>
<script>
import Search from '~/components/search.vue'
import LinkButton from '~/components/link-button.vue'
// import appList from '~/static/app-list.json'
// import gamelist from '~/static/game-list.json'
export default {
async asyncData () {
// const { default: appList } = await import('~/static/app-list.json')
// const { default: gamelist } = await import('~/static/game-list.json')
const { allList } = await import('~/helpers/get-list.js')
const { categories } = await import('~/helpers/categories.js')
// Map Categories into category list
const categoryList = Object.fromEntries(Object.entries(categories).map( ( entry ) => {
entry[1].appNamesList = []
return entry
} ))
// Delete no-category
delete categoryList['no-category']
allList.forEach( app => {
// Find and store all categories
// console.log('app.category.slug', app.category.slug)
if (categoryList.hasOwnProperty(app.category.slug)) {
categoryList[app.category.slug].appNamesList.push(app.name)
return
}
categoryList[app.category.slug] = {
// Merg in category data from app
...app.category,
// Merge in category data from category file
...categories[app.category.slug],
appNamesList: [ app.name ]
}
})
// Add App Names Text into categoryList
Object.keys(categoryList).map(function(key, index) {
const category = categoryList[key]
categoryList[key] = {
...category,
appNames: category.appNamesList.slice(0, 25).join(', ') + ', etc...'
}
})
// console.log('categoryList', categoryList)
return {
categoryList
}
},
components: {
Search,
LinkButton
},
data: function () {
return {}
},
// computed: {
// categoryList () {
// return categoryList
// }
// },
head() {
return {
title: `Categories of App Support for Apple Silicon - Does It ARM`,
// meta: [
// // hid is used as unique identifier. Do not use `vmid` for it as it will not work
// {
// hid: 'description',
// name: 'description',
// content: 'My custom description'
// }
// ]
}
}
}
</script>

View file

@ -1,204 +0,0 @@
<template>
<section class="container py-24">
<div class="flex flex-col items-center space-y-12">
<div class="summary space-y-6 max-w-2xl">
<h1 class="title text-3xl md:text-5xl font-hairline leading-tight text-center">
{{ device.name }}
</h1>
<div
v-if="device.description"
class="md:text-md text-center"
>
{{ device.description }}
</div>
<div
v-if="supportedAppList.length !== 0"
class="md:text-md text-center"
>
Supported apps include {{ supportedAppList.join(', ') }}.
</div>
<div class="flex justify-center py-3">
<LinkButton
v-if="device.amazonUrl"
:href="device.amazonUrl"
target="_blank"
>
Check Pricing
</LinkButton>
</div>
</div>
<div class="search-apps w-full flex flex-col items-center space-y-4">
<h2
class="subtitle md:text-lg font-bold text-center"
>
Search app support for {{ device.name }}
</h2>
<Search
:app-list="deviceAppList"
:quick-buttons="quickButtons"
:autofocus="false"
:initial-limit="50"
@update:query="query = $event"
>
<template v-slot:before-search>
<div class="empty-div" />
</template>
</Search>
</div>
<ListEndButtons :query="query" />
</div>
</section>
</template>
<script>
import Search from '~/components/search.vue'
import LinkButton from '~/components/link-button.vue'
import ListEndButtons from '~/components/list-end-buttons.vue'
// import { categories } from '~/helpers/categories.js'
import { deviceSupportsApp } from '~/helpers/devices.js'
export default {
async asyncData ({ params: { slug } }) {
const { default: Chance } = await import('chance')
const { allList } = await import('~/helpers/get-list.js')
const { default: deviceList } = await import('~/static/device-list.json')
const charCode = slug.charCodeAt( slug.length-2 )
const shuffler = new Chance( charCode )
const device = deviceList.find( device => {
return device.slug === slug
})
// console.log( 'device', device )
const deviceAppList = allList.map( app => {
const appIsSupported = deviceSupportsApp( device, app )
return {
name: app.name,
status: app.status,
slug: app.slug,
// endpoint: app.endpoint,
text: appIsSupported ? `✅ Supported on ${device.name}` : `🚫 Not yet reported working on ${device.name}`,
lastUpdated: app.lastUpdated,
category: app.category,
// searchLinks: makeAppSearchLinks( app, (new Set(videoList)) )
}
})
const supportedApps = deviceAppList.filter( app => {
const supported = app.text.startsWith('✅')
const hasNotAllowedCategory = ([
'no-category',
'homebrew',
'games',
]).some( categorySlug => (app.category.slug === categorySlug) )
// console.log('hasNonStandardCategory', app.category.slug, hasNonStandardCategory)
return supported && !hasNotAllowedCategory
})
const featuredApps = shuffler.shuffle( supportedApps ).slice(0, 12)
// console.log('featuredApps', featuredApps[0])
return {
slug,
device,
featuredApps,
deviceAppList
}
},
components: {
Search,
LinkButton,
ListEndButtons
},
data: function () {
return {
query: '',
quickButtons: []
}
},
computed: {
supportedAppList () {
return this.featuredApps.map(app => app.name)
},
title () {
return `App support list for ${this.device.name}`
},
description () {
return `Check the the latest reported support status of apps and software on ${this.device.name}.`
},
structuredData () {
return {
"@context": "https://schema.org",
// https://developers.google.com/search/docs/data-types/faqpage
// https://schema.org/FAQPage
"@type": "FAQPage",
"mainEntity": this.deviceAppList.map( app => {
return {
// https://schema.org/Question
"@type": "Question",
"name": `Does ${app.name} work on ${ this.device.name }?`,
"acceptedAnswer": {
// https://schema.org/Answer
"@type": "Answer",
"text": app.text
}
}
})
}
}
},
head() {
return {
title: this.title,
meta: [
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
{
'hid': 'description',
'name': 'description',
'content': this.description
},
// Twitter Card
{
'hid': 'twitter:title',
'property': 'twitter:title',
'content': this.title
},
{
'hid': 'twitter:description',
'property': 'twitter:description',
'content': this.description
},
{
'property': 'twitter:url',
'content': `${process.env.URL}${this.$nuxt.$route.path}`
},
],
__dangerouslyDisableSanitizers: ['script'],
script: [{ innerHTML: JSON.stringify(this.structuredData), type: 'application/ld+json' }]
}
}
}
</script>

View file

@ -1,76 +0,0 @@
<template>
<section class="container py-24">
<div class="flex flex-col">
<h1 class="title text-2xl leading-tight mb-6">
Devices
</h1>
<div class="line-separator border-white border-t-2 mb-12" />
<!-- deviceList: {{ deviceList }} -->
<ul class="device-list space-y-3">
<li
v-for="(device, i) in deviceList"
:key="`${device.slug}-${i}`"
:ref="`${device.slug}-row`"
class="relative"
>
<!-- device.endpoint: {{ device.endpoint }} -->
<a
:href="device.endpoint"
class="flex justify-start items-center inset-x-0 text-3xl md:text-4xl hover:bg-darkest border-2 border-white border-opacity-0 hover:border-opacity-50 focus:outline-none focus:bg-gray-50 duration-300 ease-in-out rounded-lg space-x-3 -mx-5 px-5 md:pr-64 py-3"
style="transition-property: border;"
>
<div class="font-hairline">
<div>{{ device.name }}</div>
<!-- <div class="text-xs opacity-75 mb-3">{{ device.appNames }}</div> -->
</div>
<div></div>
</a>
</li>
</ul>
</div>
</section>
</template>
<script>
import LinkButton from '~/components/link-button.vue'
export default {
async asyncData () {
const { default: deviceList } = await import('~/static/device-list.json')
return {
deviceList
}
},
components: {
LinkButton
},
data: function () {
return {}
},
// computed: {
// deviceList () {
// return deviceList
// }
// },
head() {
return {
title: `Categories of App Support for Apple Silicon - Does It ARM`,
// meta: [
// // hid is used as unique identifier. Do not use `vmid` for it as it will not work
// {
// hid: 'description',
// name: 'description',
// content: 'My custom description'
// }
// ]
}
}
}
</script>

View file

@ -1,36 +0,0 @@
<template>
<AllUpdatesSubscribe
class="w-100 h-100 absolute inset-0 flex justify-center items-center"
/>
</template>
<script>
import AllUpdatesSubscribe from '~/components/all-updates-subscribe.vue'
export default {
layout: 'embed',
components: {
AllUpdatesSubscribe
},
data: function () {
return {}
},
head() {
return {
title: 'Subscribe',
// meta: [
// // hid is used as unique identifier. Do not use `vmid` for it as it will not work
// {
// hid: 'description',
// name: 'description',
// content: 'My custom description'
// }
// ]
}
}
}
</script>

View file

@ -1,80 +0,0 @@
<template>
<VideoPlayer
v-if="youtubeId !== null"
:video="video"
class="w-100 h-100 absolute inset-0 flex justify-center items-center"
>
<template v-slot:cover-bottom>
<div class="page-heading h-full flex items-end md:p-4">
<h1 class="title text-xs text-left md:text-2xl font-bold">
{{ video.name }}
</h1>
</div>
</template>
</VideoPlayer>
</template>
<script>
import VideoPlayer from '~/components/video/player.vue'
export default {
layout: 'embed',
components: {
VideoPlayer
},
data: function () {
return {
youtubeId: null,
name: ''
}
},
computed: {
video () {
return {
name: this.name,
id: this.youtubeId,
timestamps: [],
thumbnail: {
sizes: '(max-width: 640px) 100vw, 640px',
srcset: `https://i.ytimg.com/vi/${this.youtubeId}/default.jpg 120w, https://i.ytimg.com/vi/${this.youtubeId}/mqdefault.jpg 320w, https://i.ytimg.com/vi/${this.youtubeId}/hqdefault.jpg 480w, https://i.ytimg.com/vi/${this.youtubeId}/sddefault.jpg 640w`,
src: `https://i.ytimg.com/vi/${this.youtubeId}/default.jpg`
},
}
}
},
head() {
return {
title: 'Video - Does It ARM',
// meta: [
// // hid is used as unique identifier. Do not use `vmid` for it as it will not work
// {
// hid: 'description',
// name: 'description',
// content: 'My custom description'
// }
// ]
}
},
mounted () {
// this.youtubeId = 'NDwmqJYJq9s'
// console.log('window', window)
if ( process.client ) {
const urlParams = new URLSearchParams(window.location.search)
this.youtubeId = urlParams.get('youtube-id')
this.name = urlParams.get('name')
}
// console.log('this.youtubeId', this.youtubeId)
}
}
</script>

View file

@ -1,84 +0,0 @@
<template>
<section class="container py-32">
<div class="flex flex-col items-center text-center">
<h1 class="title text-sm md:text-2xl font-bold">
Does <code>{{ app.name }}</code> work on Apple Silicon when installed via Homebrew?
</h1>
<h2 class="subtitle text-2xl md:text-5xl font-bold py-6">
{{ app.text }}
</h2>
<small class="data-credit text-sm opacity-75 text-center mb-4">
<span>According to Github</span>
</small>
<div
class="comments text-sm mb-8"
v-html="app.content"
/>
<div class="links space-y-6 sm:space-x-6 mb-8">
<LinkButton
v-for="(link, i) in app.relatedLinks"
:key="i"
:href="link.href"
target="_blank"
class=""
>{{ (i === 0) ? 'View' : link.label }}</LinkButton>
</div>
</div>
</section>
</template>
<script>
import LinkButton from '~/components/link-button.vue'
// import EmailSubscribe from '~/components/email-subscribe.vue'
// import homebrewList from '~/static/homebrew-list.json'
export default {
components: {
LinkButton,
// EmailSubscribe
},
async asyncData ({ params: { slug }, payload: { app } }) {
return {
slug,
app//: homebrewList.find(app => (app.slug === slug))
}
},
head() {
return {
title: `Does ${this.app.name} work on Apple Silicon?`,
meta: [
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
{
'hid': 'description',
'name': 'description',
'content': `Check the the latest reported support status of ${this.app.name} on Apple Silicon and ${ process.env.npm_package_config_verbiage_processors } Processors when installed via Homebrew. `
},
// Twitter Card
{
'hid': 'twitter:title',
'property': 'twitter:title',
'content': `Does ${this.app.name} work on Apple Silicon?`
},
{
'hid': 'twitter:description',
'property': 'twitter:description',
'content': `Check the the latest reported support status of ${this.app.name} on Apple Silicon and ${ process.env.npm_package_config_verbiage_processors } Processors when installed via Homebrew. `
},
{
'property': 'twitter:url',
'content': `${process.env.URL}${this.$nuxt.$route.path}`
},
]
}
}
}
</script>

View file

@ -1,226 +0,0 @@
<template>
<section class="container pb-16">
<div class="flex flex-col items-center text-center space-y-8">
<template
v-if="video"
>
<VideoPlayer
:video="video"
class="pt-16"
/>
<ChannelCredit
:video="video"
class="flex w-full justify-start md:px-10"
/>
</template>
<template v-else>
<div
:style="{
'left': '50%',
'right': '50%',
'margin-left': '-50vw',
'margin-right': '-50vw'
}"
class="video-canvas w-screen flex justify-center bg-black pt-16"
>
<div class="ratio-wrapper w-full max-w-4xl">
<div class="relative overflow-hidden w-full pb-16/9">
<div class="absolute h-full w-full flex justify-center items-center">
<div class="message text-4xl md:text-6xl font-hairline leading-tight text-center">No videos yet</div>
</div>
</div>
</div>
</div>
</template>
<div
v-for="(row, key) in videoRows"
:key="key"
class="w-full max-w-4xl"
>
<div
v-if="row.videos.length !== 0"
:class="`${key}-videos w-full`"
>
<h2 class="subtitle text-xl md:text-2xl font-bold mb-3">
{{ row.heading }}
</h2>
<!-- <pre class="text-left">{{ benchmarkVideos }}</pre> -->
<VideoRow
:videos="row.videos"
:active-video-id="activeVideoId"
/>
</div>
</div>
</div>
</section>
</template>
<script>
import LinkButton from '~/components/link-button.vue'
import EmailSubscribe from '~/components/email-subscribe.vue'
import VideoRow from '~/components/video/row.vue'
import VideoPlayer from '~/components/video/player.vue'
import ChannelCredit from '~/components/video/channel-credit.vue'
export default {
components: {
LinkButton,
EmailSubscribe,
VideoRow,
VideoPlayer,
ChannelCredit
},
asyncData ({ params: { slug }, payload: { app, allVideos } }) {
// const { allVideoAppsList } = await import('~/helpers/get-list.js')
// const { default: videoList } = await import('~/static/video-list.json')
// const { videosRelatedToApp } = await import('~/helpers/related.js')
// const app = allVideoAppsList.find(app => (app.slug === slug))
// // const submitVideoCard = {
// // endpoint: `https://docs.google.com/forms/d/e/1FAIpQLSeEVGM9vE7VcfLMy6fJkfU70X2VZ60rHDyhDQLtnAN4nso0WA/viewform?usp=pp_url&entry.1018125313=${app.name}`
// // }
// // const featuredApps = []
// const relatedVideos = videosRelatedToApp( app, videoList ).map(video => {
// // console.log('video', video)
// return {
// ...video,
// // endpoint: `#${video.id}`
// }
// })
// console.log({
// app,
// allVideos,
// // submitVideoCard
// })
return {
app,
allVideos,
// submitVideoCard
}
},
data: function () {
return {
activeVideoIndex: 0,
videoRows: {
'benchmarks': {
heading: 'Benchmark Videos',
matchesCondition: video => video.tags.includes('benchmark'),
videos: []
},
'performance': {
heading: 'Performance Videos',
matchesCondition: video => video.tags.includes('performance'),
videos: []
},
'other': {
heading: 'More Videos',
// Always true
matchesCondition: () => true,
videos: []
}
}
}
},
computed: {
video () {
return this.allVideos[this.activeVideoIndex]
},
title () {
return `${this.app.name} Benchmarks for Apple Silicon - Does It ARM`
},
description () {
return `Apple Silicon gaming benchmark, performance, and support videos for ${this.app.name}`
},
activeVideoId () {
return (this.video === Object(this.video)) ? this.video.id : null
}
},
created () {
// Move videos to relevant categories
this.allVideos.forEach((video, index) => {
// console.log('video.name', video.name)
// console.log('video.tags', video.tags)
// Look through row conditions to see if video matches
for (const row in this.videoRows) {
if( this.videoRows[row].matchesCondition(video) ) {
// Add the matching video
this.videoRows[row].videos.push(video)
return
}
}
})
// console.log('lengths', Object.values(this.videoRows).map(row => [row.heading, row.videos.length]))
},
mounted () {
window.onhashchange = this.loadVideoFromHash
if (location.hash.length !== 0) this.loadVideoFromHash()
},
methods: {
loadVideoFromHash () {
// console.log('location.hash', location.hash)
// Separate the video id from our window hash
const hashId = location.hash.split('#')[1]
// Find the index of the video with the matching hash
const newVideoIndex = this.allVideos.findIndex(video => {
return video.id === hashId
})
console.log('newVideoIndex', newVideoIndex)
// Load in the index to load out video
this.activeVideoIndex = newVideoIndex
window.scroll({ top: 0, behavior: 'smooth' })
}
},
head() {
return {
title: this.title,
meta: [
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
{
'hid': 'description',
'name': 'description',
'content': this.description
},
// Twitter Card
{
'hid': 'twitter:title',
'property': 'twitter:title',
'content': this.title
},
{
'hid': 'twitter:description',
'property': 'twitter:description',
'content': this.description
},
{
'property': 'twitter:url',
'content': `${process.env.URL}${this.$nuxt.$route.path}`
},
]
}
}
}
</script>

View file

@ -1,178 +0,0 @@
<template>
<section class="container py-32">
<div class="flex flex-col items-center text-center">
<div class="intro-content flex flex-col items-center text-center min-h-3/4-screen md:min-h-0">
<h1 class="title text-sm md:text-2xl font-bold">
Does {{ app.name }} work on Apple Silicon?
</h1>
<h2 class="subtitle text-2xl md:text-5xl font-bold py-6">
{{ app.text }}
</h2>
<ThomasCredit />
</div>
<div
v-if="relatedVideos.length !== 0"
class="related-videos w-full"
>
<h2 class="subtitle text-xl md:text-2xl font-bold mb-3">
Related Videos
</h2>
<VideoRow
:videos="relatedVideos"
/>
</div>
<h2 class="subtitle text-xl md:text-2xl font-bold py-6">
Reports
</h2>
<ul class="flex flex-col md:flex-row space-x-0 space-y-4 md:space-y-0 md:space-x-4 mb-4">
<li
v-for="(report, i) in app.reports"
:key="`${app.slug}-${i}`"
class="col-span-1 rounded-lg border w-full md:w-64"
>
<div class="w-full flex items-center justify-between p-6">
<div class="flex-1">
<div class="space-x-3">
<h3 class="text-sm leading-5 font-bold">{{ report['Specs'] }}</h3>
<span class="flex-shrink-0 inline-block px-2 py-0.5 text-teal-800 text-xs leading-4 font-bold bg-teal-100 rounded-full">{{ report['FPS'] }}</span>
</div>
<p class="mt-1 text-sm leading-5">{{ report['Notes'] }}</p>
<p
v-if="report['Resolution'].length !== 0"
class="mt-1 text-sm leading-5"
>
🖥 {{ report['Resolution'] }}
</p>
<p
v-if="report['Settings'].length !== 0"
class="mt-1 text-sm leading-5"
>
{{ report['Settings'] }}
</p>
</div>
</div>
<div
v-if="report['Source'].includes('https://')"
class="border-t border-gray-200"
>
<div class="-mt-px flex">
<div class="w-0 flex-1 flex border-r border-gray-200">
<a
:href="report['Source']"
class="relative -mr-px w-0 flex-1 inline-flex items-center justify-center py-4 text-sm leading-5 font-bold border border-transparent rounded-bl-lg hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 transition ease-in-out duration-150"
>
<!-- Heroicon name: mail -->
<svg
class="w-5 h-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z" />
<path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" />
</svg>
<span class="ml-3 opacity-75">Source</span>
</a>
</div>
</div>
</div>
</li>
</ul>
<div class="report-links py-24 shadow-none">
<!-- https://eric.blog/2016/01/08/prefilling-github-issues/ -->
<a
:href="`https://forms.gle/29GWt85i1G1L7Ttj8`"
target="_blank"
class="text-xs"
rel="noopener"
>Report Update</a>
</div>
</div>
</section>
</template>
<script>
import { getAppEndpoint } from '~/helpers/app-derived.js'
import VideoRow from '~/components/video/row.vue'
import LinkButton from '~/components/link-button.vue'
import ThomasCredit from '~/components/thomas-credit.vue'
export default {
components: {
VideoRow,
LinkButton,
ThomasCredit
},
async asyncData ({ params: { slug } }) {
const { default: gameList } = await import('~/static/game-list.json')
const { default: videoList } = await import('~/static/video-list.json')
const { videosRelatedToApp } = await import('~/helpers/related.js')
const app = gameList.find(app => (app.slug === slug))
const relatedVideos = videosRelatedToApp( app, (new Set(videoList)) )
// Find other videos that also feature this video's app
// for (const video of videoList) {
// if (!video.apps.includes(app.slug)) continue
// relatedVideos.push(video)
// }
return {
slug,
app,
relatedVideos: relatedVideos.map(video => {
// console.log('video', video)
return {
...video,
endpoint: `${getAppEndpoint(app)}/benchmarks#${video.id}`
}
})
}
},
head() {
return {
title: `Does ${this.app.name} work on Apple Silicon?`,
meta: [
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
{
'hid': 'description',
'name': 'description',
'content': `Check the the latest reported support status of ${this.app.name} on Apple Silicon and ${ process.env.npm_package_config_verbiage_processors } Processors for gaming. `
},
// Twitter Card
{
'hid': 'twitter:title',
'property': 'twitter:title',
'content': `Does ${this.app.name} work on Apple Silicon?`
},
{
'hid': 'twitter:description',
'property': 'twitter:description',
'content': `Check the the latest reported support status of ${this.app.name} on Apple Silicon and ${ process.env.npm_package_config_verbiage_processors } Processors for gaming. `
},
{
'property': 'twitter:url',
'content': `${process.env.URL}${this.$nuxt.$route.path}`
},
]
}
}
}
</script>

View file

@ -1,103 +0,0 @@
<template>
<section class="container py-24">
<div class="flex flex-col items-center">
<h1 class="title text-4xl md:text-6xl font-hairline leading-tight text-center">
Does It ARM?
</h1>
<h2 class="subtitle md:text-xl text-center">
Games that are reported to support Apple Silicon
</h2>
<ThomasCredit />
<Search
:app-list="gameList"
:quick-buttons="quickButtons"
no-email-subscribe
@update:query="query = $event"
/>
<LinkButton
:href="`https://forms.gle/29GWt85i1G1L7Ttj8`"
>
Report a Game
</LinkButton>
</div>
</section>
</template>
<script>
import Search from '~/components/search.vue'
import LinkButton from '~/components/link-button.vue'
import ThomasCredit from '~/components/thomas-credit.vue'
import gameList from '~/static/game-list.json'
export default {
async asyncData () {
const { sortedAppList, allList, allVideoAppsList, makeAppSearchLinks } = await import('~/helpers/get-list.js')
const { default: gameList } = await import('~/static/game-list.json')
const { default: videoList } = await import('~/static/video-list.json')
return {
// Map game list
gameList: gameList.map( app => {
return {
name: app.name,
status: app.status,
slug: app.slug,
// endpoint: app.endpoint,
text: app.text,
lastUpdated: app.lastUpdated,
category: app.category,
searchLinks: makeAppSearchLinks( app, (new Set(videoList)) )
}
})
}
},
components: {
Search,
LinkButton,
ThomasCredit
},
data: function () {
return {
query: '',
quickButtons: [
{
label: '✅ Native Support',
query: 'status:native'
},
{
label: '✳️ Rosetta',
query: 'status:rosetta'
},
{
label: '🚫 Unsupported',
query: 'status:no'
}
]
}
},
computed: {
// gameList() {
// return gameList
// }
},
head() {
return {
title: `Games supported on Apple Silicon - Does It ARM`,
// meta: [
// // hid is used as unique identifier. Do not use `vmid` for it as it will not work
// {
// hid: 'description',
// name: 'description',
// content: 'My custom description'
// }
// ]
}
}
}
</script>

View file

@ -1,246 +0,0 @@
<template>
<section class="container py-24">
<div class="flex flex-col items-center space-y-4">
<div class="hero">
<h1 class="title text-3xl md:text-6xl font-hairline leading-tight text-center">
Does It ARM?
</h1>
<h2 class="subtitle md:text-xl text-center">
Apps that are reported to support Apple Silicon
</h2>
</div>
<Search
:app-list="allList"
:quick-buttons="quickButtons"
:initial-limit="100"
@update:query="onQueryUpdate"
>
<template v-slot:before-search>
<div class="list-summary-wrapper flex justify-center text-center text-sm">
<ListSummary
:custom-numbers="customSummaryNumbers"
class="max-w-4xl"
/>
</div>
</template>
</Search>
<ListEndButtons :query="query" />
<AllUpdatesSubscribe
:input-class-groups="{
shadow: 'hover:neumorphic-shadow',
bg: '',
focus: 'bg-transparent neumorphic-shadow pl-8',
blur: 'placeholder-white text-center border border-transparent bg-transparent opacity-50 hover:opacity-100 px-3',
}"
class="my-12"
/>
</div>
</section>
</template>
<script>
import axios from 'axios'
import getListSummaryNumbers from '~/helpers/get-list-summary-numbers.js'
import Search from '~/components/search.vue'
import LinkButton from '~/components/link-button.vue'
import AllUpdatesSubscribe from '~/components/all-updates-subscribe.vue'
import ListSummary from '~/components/list-summary.vue'
import ListEndButtons from '~/components/list-end-buttons.vue'
export default {
async asyncData () {
// const { default: appList } = await import('~/static/app-list.json')
// const { default: gamelist } = await import('~/static/game-list.json')
const { sortedAppList, allList, allVideoAppsList, makeAppSearchLinks } = await import('~/helpers/get-list.js')
const { default: videoList } = await import('~/static/video-list.json')
const allAppSearchLinks = {}
// console.log('allVideoAppsList', allVideoAppsList)
allVideoAppsList.forEach( app => {
// Make the search links
const searchLinks = makeAppSearchLinks( app, (new Set(videoList)) )
// If there are more than zero
// add them to our list
if (searchLinks.length > 0) {
allAppSearchLinks[app.slug] = searchLinks
}
})
return {
// Filter app list to leave out data not needed for search
initialAppList: sortedAppList.map( app => {
const searchLinks = allAppSearchLinks?.[app.slug] || []
// if (typeof allAppSearchLinks[app.slug] !== 'undefined') {
// searchLinks = allAppSearchLinks[app.slug]
// }
return {
name: app.name,
status: app.status,
slug: app.slug,
// endpoint: app.endpoint,
text: app.text,
lastUpdated: app.lastUpdated,
category: app.category,
searchLinks
}
}),
allAppSearchLinks,
customSummaryNumbers: getListSummaryNumbers(allList)
}
},
components: {
Search,
LinkButton,
AllUpdatesSubscribe,
ListSummary,
ListEndButtons
},
data: function () {
return {
query: '',
fetchedAppList: [],
quickButtons: [
{
label: '✅ Native Support',
query: 'status:native'
},
{
label: '✳️ Rosetta',
query: 'status:rosetta'
},
{
label: '🚫 Unsupported',
query: 'status:no'
},
{
label: '🎮 Games',
query: 'Games'
},
{
label: '🍺 Homebrew Formulae',
query: 'Homebrew'
},
{
label: 'Music Tools',
query: 'Music'
},
{
label: 'Developer Tools',
query: 'Developer'
},
{
label: 'Photo Tools',
query: 'Photo'
},
{
label: 'Video Tools',
query: 'Video'
},
{
label: 'Productivity Tools',
query: 'Productivity'
},
]
}
},
computed: {
title () {
return `Apple Silicon and ${ process.env.npm_package_config_verbiage_processors } app and game compatibility list`
},
description () {
return `List of compatibility apps and games for Apple Silicon and the ${ process.env.npm_package_config_verbiage_processors } Processors including performance reports and benchmarks`
},
allList () {
return [
...this.initialAppList,
...this.fetchedAppList
]
}
},
methods: {
async onQueryUpdate ( $event ) {
// console.log('$event', $event)
this.query = $event
// If fetched lists have already been loaded in
// OR if there's no query
// then stop
if (this.fetchedAppList.length !== 0 || this.query.trim().length === 0) return
// console.log('this.allAppSearchLinks', this.allAppSearchLinks)
const fetchedListUrls = [
'/game-list.json',
'/homebrew-list.json'
]
const fetchedLists = await Promise.all(fetchedListUrls.map( async listUrl => {
// Fetch List
const response = await axios.get(listUrl)
// Extract apps from response data
const fetchedApps = response.data
return fetchedApps
}))
// console.log('fetchedLists', fetchedLists)
this.fetchedAppList = fetchedLists.flat(1).map( app => {
const searchLinks = this.allAppSearchLinks?.[app.slug] || []
return {
...app,
searchLinks
}
})
return
}
},
head() {
return {
title: this.title,
meta: [
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
{
'hid': 'description',
'name': 'description',
'content': this.description
},
// Twitter Card
{
'hid': 'twitter:title',
'property': 'twitter:title',
'content': this.title
},
{
'hid': 'twitter:description',
'property': 'twitter:description',
'content': this.description
},
{
'property': 'twitter:url',
'content': `${process.env.URL}${this.$nuxt.$route.path}`
},
]
}
}
}
</script>

View file

@ -1,185 +0,0 @@
<template>
<section class="container py-24">
<div class="flex flex-col items-center">
<h1 class="title text-3xl md:text-5xl font-hairline leading-tight text-center pb-4">
{{ pluralLabel }} that are reported to support Apple Silicon
</h1>
<h2
v-if="supportedAppList.length !== 0"
class="subtitle md:text-xl text-center"
>
Supported apps include {{ supportedAppList.join(', ') }}.
</h2>
<Search
:app-list="categoryAppList"
:quick-buttons="quickButtons"
@update:query="query = $event"
/>
<div class="flex flex-col md:flex-row space-x-0 space-y-4 md:space-y-0 md:space-x-4">
<template v-if="category.requestLinks">
<LinkButton
v-for="link in category.requestLinks"
:key="link.label"
:href="link.href"
class="text-xs"
>
{{ link.label }}
</LinkButton>
</template>
<template v-else>
<ListEndButtons :query="query" />
</template>
</div>
</div>
</section>
</template>
<script>
import Search from '~/components/search.vue'
import LinkButton from '~/components/link-button.vue'
import ListEndButtons from '~/components/list-end-buttons.vue'
import { categories, getAppCategory } from '~/helpers/categories.js'
export default {
async asyncData ({ params: { slug } }) {
const { sortedAppList, allList, allVideoAppsList, makeAppSearchLinks } = await import('~/helpers/get-list.js')
const { default: gameList } = await import('~/static/game-list.json')
const { default: videoList } = await import('~/static/video-list.json')
const filteredList = allList.filter(app => {
return app.category.slug === slug
})
return {
slug,
categoryAppList: filteredList.map( app => {
return {
name: app.name,
status: app.status,
slug: app.slug,
// endpoint: app.endpoint,
text: app.text,
lastUpdated: app.lastUpdated,
category: app.category,
searchLinks: makeAppSearchLinks( app, (new Set(videoList)) )
}
})
}
},
components: {
Search,
LinkButton,
ListEndButtons
},
data: function () {
return {
query: '',
quickButtons: [
{
label: '✅ Native Support',
query: 'status:native'
},
{
label: '✳️ Rosetta',
query: 'status:rosetta'
},
{
label: '🚫 Unsupported',
query: 'status:no'
},
]
}
},
computed: {
category () {
if ( categories.hasOwnProperty( this.slug ) ) {
return categories[this.slug]
}
// Try to find the category info within the passed apps
const appWithCategory = this.categoryAppList.find( app => {
return app.category.slug === this.slug
})
// console.log('appWithCategory', appWithCategory)
return appWithCategory.category
},
pluralLabel () {
if ( this.category.hasOwnProperty('pluralLabel') ) {
return this.category.pluralLabel
}
return this.category.label
},
supportedAppList () {
return this.categoryAppList.filter(app => {
return app.status.includes('yes')
}).map(app => app.name)
},
title () {
return `List of ${this.pluralLabel || this.category.label} that work on Apple Silicon?`
},
description () {
return `Check the the latest reported support status of ${this.pluralLabel || this.category.label} on Apple Silicon and ${ process.env.npm_package_config_verbiage_processors } Processors. `
},
structuredData () {
return {
"@context": "https://schema.org",
// https://developers.google.com/search/docs/data-types/faqpage
// https://schema.org/FAQPage
"@type": "FAQPage",
"mainEntity": this.categoryAppList.map( app => {
return {
// https://schema.org/Question
"@type": "Question",
"name": `Does ${app.name} work on Apple Silicon and ${ process.env.npm_package_config_verbiage_processors } Macs?`,
"acceptedAnswer": {
// https://schema.org/Answer
"@type": "Answer",
"text": app.text
}
}
})
}
}
},
head() {
return {
title: this.title,
meta: [
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
{
'hid': 'description',
'name': 'description',
'content': this.description
},
// Twitter Card
{
'hid': 'twitter:title',
'property': 'twitter:title',
'content': this.title
},
{
'hid': 'twitter:description',
'property': 'twitter:description',
'content': this.description
},
{
'property': 'twitter:url',
'content': `${process.env.URL}${this.$nuxt.$route.path}`
},
],
__dangerouslyDisableSanitizers: ['script'],
script: [{ innerHTML: JSON.stringify(this.structuredData), type: 'application/ld+json' }]
}
}
}
</script>

View file

@ -1,32 +0,0 @@
<template>
<section class="container py-24">
<!-- __template -->
</section>
</template>
<script>
export default {
data: function () {
return {}
},
// computed: {
// categoryList () {
// return categoryList
// }
// },
head() {
return {
title: '__template',
// meta: [
// // hid is used as unique identifier. Do not use `vmid` for it as it will not work
// {
// hid: 'description',
// name: 'description',
// content: 'My custom description'
// }
// ]
}
}
}
</script>

View file

@ -1,189 +0,0 @@
<template>
<section class="container pb-16">
<div class="flex flex-col items-center text-center space-y-6">
<VideoPlayer
:video="video"
class="pt-16"
>
<template v-slot:cover-bottom>
<div class="page-heading h-full flex items-end md:p-4">
<h1 class="title text-xs text-left md:text-2xl font-bold">
{{ video.name }}
</h1>
</div>
</template>
</VideoPlayer>
<div
class="md:flex w-full justify-between space-y-4 md:space-y-0 md:px-10"
>
<!-- <h1 class="title text-lg md:text-2xl font-bold">
{{ video.name }}
</h1> -->
<ChannelCredit
:video="video"
/>
</div>
<hr class="w-full" >
<div
v-if="featuredApps.length !== 0"
class="related-apps w-full"
>
<h2 class="subtitle text-xl md:text-2xl font-bold mb-3">
Related Apps
</h2>
<div class="featured-apps overflow-x-auto overflow-y-visible whitespace-no-wrap py-2 space-x-2">
<LinkButton
v-for="app in featuredApps"
:key="app.slug"
:href="getAppEndpoint(app)"
:class="[
'inline-block text-xs rounded-lg py-1 px-2',
]"
:class-groups="{
shadow: 'neumorphic-shadow-inner'
}"
>{{ app.name }}</LinkButton>
</div>
</div>
<div class="related-videos w-full">
<h2 class="subtitle text-xl md:text-2xl font-bold mb-3">
Related Videos
</h2>
<VideoRow
:videos="relatedVideos"
/>
</div>
<!-- video: {{ video }} -->
<!-- <div class="links space-y-6 sm:space-x-6 mb-8">
<LinkButton
v-for="(link, i) in app.relatedLinks"
:key="i"
:href="link.href"
target="_blank"
class=""
>{{ (i === 0) ? 'View' : link.label }}</LinkButton>
</div> -->
</div>
</section>
</template>
<script>
import { getAppEndpoint } from '~/helpers/app-derived.js'
import { buildVideoStructuredData } from '~/helpers/structured-data.js'
import LinkButton from '~/components/link-button.vue'
import EmailSubscribe from '~/components/email-subscribe.vue'
import VideoRow from '~/components/video/row.vue'
import VideoPlayer from '~/components/video/player.vue'
import ChannelCredit from '~/components/video/channel-credit.vue'
function makeFeaturedAppsString ( featuredApps ) {
return featuredApps.slice(0, 5).map(app => app.name).join(', ')
}
export default {
components: {
LinkButton,
EmailSubscribe,
VideoRow,
VideoPlayer,
ChannelCredit
},
async asyncData ( data ) {
const {
params: { slug },
route
} = data
let {
payload
} = data
// Manually get payload as fallback
// Uncomment for dev
// if ( payload === undefined ) {
// // Read back the JSON we just wrote to ensure it exists
// const { default: savedList } = await import('~/static/nuxt-endpoints.json')
// const endpoint = savedList.find( resource => {
// return resource.route === route.path
// } )
// payload = endpoint.payload
// }
return {
video: payload.video,
featuredApps: payload.featuredApps,
relatedVideos: payload.relatedVideos
}
},
computed: {
title () {
return `${this.video.name} - Does It ARM`
},
description () {
const featuredAppsString = makeFeaturedAppsString( this.featuredApps )
return `Apple Silicon performance and support videos for ${featuredAppsString}`
},
},
methods: {
getAppEndpoint
},
head() {
const structuredData = buildVideoStructuredData( this.video, this.featuredApps, {
siteUrl: this.$config.siteUrl
} )
return {
title: this.title,
meta: [
// hid is used as unique identifier. Do not use `vmid` for it as it will not work
{
'hid': 'description',
'name': 'description',
'content': this.description
},
// Twitter Card
{
'hid': 'twitter:title',
'property': 'twitter:title',
'content': this.title
},
{
'hid': 'twitter:description',
'property': 'twitter:description',
'content': this.description
},
{
'property': 'twitter:url',
'content': `${process.env.URL}${this.$nuxt.$route.path}`
},
],
__dangerouslyDisableSanitizers: ['script'],
script: [{ innerHTML: JSON.stringify( structuredData ), type: 'application/ld+json' }]
}
}
}
</script>