mirror of
https://github.com/ThatGuySam/doesitarm.git
synced 2026-05-18 06:44:46 -07:00
Merge branch 'master' into develop
This commit is contained in:
commit
2176b0fabd
22 changed files with 831 additions and 114 deletions
2
.nvmrc
2
.nvmrc
|
|
@ -1 +1 @@
|
|||
v15.11.0
|
||||
v16.0.0
|
||||
|
|
|
|||
30
README.md
30
README.md
|
|
@ -63,6 +63,7 @@ Any comments, suggestions? [Let us know!](https://github.com/ThatGuySam/doesitar
|
|||
* [DataGrip](https://www.jetbrains.com/datagrip/download/#section=mac) - ✅ Yes, full native support as of v2020.3.1
|
||||
* [DBeaver](https://dbeaver.io/) - ✳️ Yes, works via Rosetta 2 using the pkg installer - [Issue Tracking](https://github.com/dbeaver/dbeaver/issues/10470)
|
||||
* [Deno](https://deno.land/) - ✅ Yes, Full Native Apple Silicon Support - [Issue](https://github.com/denoland/deno/issues/8346)
|
||||
* [Eclipse IDE](https://www.eclipse.org/downloads/) - ✳️ Yes, runs via Rosetta 2 translation - [Verification](https://github.com/ThatGuySam/doesitarm/issues/626#issue-860190467)
|
||||
* [Gitfox](https://www.gitfox.app/) - ✅ Yes, Full Native Apple Silicon Support - [Article](https://setapp.sjv.io/apple-silicon-supported-apps) [View on Setapp](https://setapp.com/apps/gitfox)
|
||||
* [Docker](https://hub.docker.com/editions/community/docker-ce-desktop-mac) - ✅ Yes, Full Native Apple Silicon Support as of v3.3.1 - [Release Notes](https://docs.docker.com/docker-for-mac/release-notes/#docker-desktop-331) [Github Issue](https://github.com/docker/for-mac/issues/4733#issuecomment-653444409)
|
||||
* [Dreamweaver](https://www.adobe.com/products/dreamweaver.html) - ✳️ Yes, works via Rosetta 2 - [Official Adobe Status Page](https://helpx.adobe.com/download-install/kb/apple-silicon-m1-chip.html)
|
||||
|
|
@ -98,6 +99,7 @@ Any comments, suggestions? [Let us know!](https://github.com/ThatGuySam/doesitar
|
|||
* [Julia Language](https://julialang.org/downloads/) - ✳️ Yes, it works via Rosetta 2 - [Github Issue](https://github.com/JuliaLang/julia/issues/36617)
|
||||
* [KiCad EDA](https://kicad.org/download/macos/) - ✳️ Yes, works via Rosetta 2 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/199#issuecomment-736253625)
|
||||
* [kitty](https://github.com/kovidgoyal/kitty/releases) - ✅ Yes, Full Native Apple Silicon Support - [Github Issue](https://github.com/kovidgoyal/kitty/issues/3238)
|
||||
* [Lens Studio](https://lensstudio.snapchat.com/download/) - ✳️ Yes, works via Rosetta 2 translation - [Supported Hardware](https://lensstudio.snapchat.com/download/)
|
||||
* [LLVM Clang](https://releases.llvm.org/download.html) - ✳️ Yes, it works via Rosetta 2 - [Apple Forums](https://developer.apple.com/forums/thread/649992)
|
||||
* [LTspice](https://www.analog.com/en/design-center/design-tools-and-calculators/ltspice-simulator.html) - ✳️ Yes, works via Rosetta 2 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/421#issuecomment-751876882)
|
||||
* [MacDown](https://macdown.uranusjr.com/) - ✳️ Yes, works via Rosetta 2 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/382)
|
||||
|
|
@ -109,7 +111,7 @@ Any comments, suggestions? [Let us know!](https://github.com/ThatGuySam/doesitar
|
|||
* [MySQL Workbench](https://dev.mysql.com/downloads/) - ✳️ Yes, works via Rosetta 2 for v8.0.21 with issues reported on newer versions - [Source](https://github.com/ThatGuySam/doesitarm/issues/173#issuecomment-730553003) [Issues](https://github.com/ThatGuySam/doesitarm/issues/173#issuecomment-763269306)
|
||||
* [Navicat Premium](https://www.navicat.com/en/products/navicat-premium) - ✳️ Yes, works via Rosetta 2 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/161#issuecomment-759768321)
|
||||
* [NixOS](https://nixos.org/download.html) - ⏹ Not yet, but it’s in development - [Github Issue](https://github.com/NixOS/nixpkgs/issues/95903)
|
||||
* [NodeJS](https://nodejs.org/en/) - ✅ Yes, Full Native Apple Silicon Support as of v15 - [M1 Benchmark](https://docs.google.com/spreadsheets/d/1g4U7LAImfEcXRihJbySZcRr32tn6WSWAtslfXltds58/edit#gid=607735373) [Version Support](https://github.com/ThatGuySam/doesitarm/issues/299#issuecomment-733210648) [Github Issue](https://github.com/nodejs/TSC/issues/886)
|
||||
* [NodeJS](https://nodejs.org/en/) - ✅ Yes, Full Native Apple Silicon Support as of v16 - [M1 Benchmark](https://docs.google.com/spreadsheets/d/1g4U7LAImfEcXRihJbySZcRr32tn6WSWAtslfXltds58/edit#gid=607735373) [Version Support](https://github.com/ThatGuySam/doesitarm/issues/299#issuecomment-733210648) [Github Issue](https://github.com/nodejs/TSC/issues/886)
|
||||
* [Nova](https://nova.app) - ✅ Yes, Full Native Apple Silicon Support as of v3 - [Official Tweet](https://twitter.com/panic/status/1326977997732134912?s=20)
|
||||
* [OCaml](https://ocaml.org/) - ⏹ Not yet, but it's currently in beta. - [Pull Status](https://github.com/ocaml/ocaml/pull/9699)
|
||||
* [Onivim2](https://v2.onivim.io/early-access-portal) - ✳️ Yes, works via Rosetta 2 Translation - [Verification](https://github.com/ThatGuySam/doesitarm/issues/601#issue-834313049) [Github Issue](https://github.com/onivim/oni2/issues/2708)
|
||||
|
|
@ -122,7 +124,7 @@ Builds - [Java on M1 Benchmarks](https://docs.google.com/spreadsheets/d/1g4U7LAI
|
|||
* [Postman](https://www.postman.com/downloads/) - ✳️ Yes, works via Rosetta 2 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/160#issuecomment-736772593)
|
||||
* [PowerShell Core](https://github.com/PowerShell/PowerShell) - ✳️ Yes, works via Rosetta 2 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/125#issuecomment-736775191)
|
||||
* [Proxyman](https://proxyman.io) - ✅ Yes, fully supported ARM and Intel Chip - [Issue](https://github.com/ProxymanApp/Proxyman/issues/686) [View on Setapp](https://setapp.sjv.io/c/2708043/635279/5114)
|
||||
* [psycopg2](https://www.psycopg.org/) - 🚫 No, not yet supported only works on Intel-based Macs - [Issue #1](https://github.com/psycopg/psycopg2/issues/1216) [Issue #2](https://github.com/psycopg/psycopg2/issues/1200)
|
||||
* [psycopg2](https://www.psycopg.org/) - ✅ Yes, Native Apple Silicon Support as of v2.8.6 via 1 or more workarounds - [Workaround #1](https://github.com/psycopg/psycopg2/issues/1200#issuecomment-820571339) [Workaround #2](https://github.com/psycopg/psycopg2/issues/1216#issuecomment-767892042) [Workaround #3](https://github.com/ThatGuySam/doesitarm/issues/628#issue-862441710)
|
||||
* [PyCharm](https://www.jetbrains.com/pycharm/download/#section=mac) - ✅ Yes, full native support as of v2020.3.1
|
||||
* [Python](https://www.python.org/) - ✅ Yes, reported working for v2.7.16, v3.8.2, and v3.9 - [PyPerformance Benchmarks](https://docs.google.com/spreadsheets/d/1g4U7LAImfEcXRihJbySZcRr32tn6WSWAtslfXltds58/edit#gid=1795089557) [Python Tracker](https://bugs.python.org/issue41100) [Github Issue](https://github.com/python/cpython/pull/22855) [Github Issue #2](https://github.com/ThatGuySam/doesitarm/issues/111)
|
||||
* [PyTorch](https://pytorch.org/) - ✅ Yes, Initial Native Apple Silicon Support for CPU only - [GPU Acceleration Status](https://github.com/pytorch/pytorch/issues/47702) [Report Update](https://github.com/ThatGuySam/doesitarm/issues/432)
|
||||
|
|
@ -250,7 +252,7 @@ Builds - [Java on M1 Benchmarks](https://docs.google.com/spreadsheets/d/1g4U7LAI
|
|||
* [Lightroom Classic](https://www.adobe.com/products/photoshop-lightroom-classic.html) - ✳️ Yes, works via Rosetta 2 with some known issues - [Known Issues](https://helpx.adobe.com/lightroom-classic/kb/macos-big-sur-compatibility.html#AppleSiliconcompatibility) [Official Adobe Status Page](https://helpx.adobe.com/download-install/kb/apple-silicon-m1-chip.html)
|
||||
* [Logoist 4](https://www.syniumsoftware.com/logoist) - ✅ Yes, Full Native Apple Silicon Support as of v4.1 - [Official News](https://www.syniumsoftware.com/synium-blog/apple-silicon-is-here-and-we-are-ready)
|
||||
* [Luminar](https://skylum.com/luminar) - ✳️ Yes, works via Rosetta 2 - [Source](https://youtu.be/CKA1YW9l8j0?t=43)
|
||||
* [MacTeX](https://www.tug.org/mactex/mactex-download.html) - ✳️ Runs via Rosetta with native support currently in development - [Article](https://www.tug.org/mactex/aboutarm.html)
|
||||
* [MacTeX](https://www.tug.org/mactex/mactex-download.html) - ✅ Yes, Full Native Apple Silicon Support as of MacTeX-2021 - [Official FAQ](https://www.tug.org/mactex/faq/index.html#qm08)
|
||||
* [Mail Designer 365](https://maildesigner365.com) - ✅ Yes, fully native support as of v2.0 - [Official page](https://www.maildesigner365.com/new-mail-designer-365-2-0-with-big-sur-optimization/)
|
||||
* [Optimage](https://optimage.app/) - ✅ Yes, Full Native Apple Silicon Support - [🧪 Apple Silicon App Tested](https://doesitarm.com/apple-silicon-app-test/)
|
||||
* [Pika](https://superhighfives.com/pika) - ✅ Yes, Full Native Apple Silicon Support - [🧪 Apple Silicon App Tested](https://doesitarm.com/apple-silicon-app-test/)
|
||||
|
|
@ -303,11 +305,26 @@ Builds - [Java on M1 Benchmarks](https://docs.google.com/spreadsheets/d/1g4U7LAI
|
|||
|
||||
#### Live Production and Performance
|
||||
* [Ableton](https://www.ableton.com/en/live/) - ✳️ Yes, it works via Rosetta 2 - [Reddit Post](https://www.reddit.com/r/ableton/comments/jrtpv6/ableton_live_11_on_apple_silicon_m1_processor/gbvxj9r?context=3)
|
||||
* [Dante Controller](https://my.audinate.com/support/downloads/download-latest-dante-software) - 🚫 No, not yet supported only recommended for Intel-based Macs - [Official Article](https://www.audinate.com/learning/faqs/dante-software-on-macos-big-sur-and-apple-m1-based-computers)
|
||||
* [Dante Via](https://my.audinate.com/support/downloads/download-latest-dante-software) - ✳️ Yes, works via Rosetta 2 translation but not yet recommended - [Official Article](https://www.audinate.com/learning/faqs/dante-software-on-macos-big-sur-and-apple-m1-based-computers)
|
||||
* [Dante Virtual Soundcard](https://my.audinate.com/support/downloads/download-latest-dante-software) - 🚫 No, not yet supported only works on Intel-based Macs - [Official Article](https://www.audinate.com/learning/faqs/dante-software-on-macos-big-sur-and-apple-m1-based-computers)
|
||||
* [djay](https://www.algoriddim.com/) - ✅ Yes, Full Native Apple Silicon Support as of v3.0 - [Release Notes](https://www.algoriddim.com/djay-pro-mac/releasenotes)
|
||||
* [Ecamm Live](https://www.ecamm.com/mac/ecammlive/?fp_ref=lsp) - ✳️ Yes, works via Rosetta 2 - [Official Article](https://support.ecamm.com/en/articles/4616420-ecamm-live-on-macos-11-big-sur-and-apple-silicon-m1-macs)
|
||||
* [Farrago](https://rogueamoeba.com/farrago/) - ✅ Yes, Initial Native Apple Silicon Support as of v1.6.0 - [Release Notes](https://rogueamoeba.com/farrago/releasenotes.php) [Official Post](https://weblog.rogueamoeba.com/2020/11/16/rogue-amoeba-software-updates-for-macos-11-big-sur-and-m1-chip-based-macs/)
|
||||
* [grandMA3 onPC](https://www.malighting.com/downloads/products/grandma3/) - 🚫 No, not yet supported only works on Intel-based Macs - [Report #1](https://forum.malighting.com/thread/4671-works-with-new-apple-m1/?postID=12236#post12236)
|
||||
* [Loopback](https://rogueamoeba.com/loopback/) - ✅ Yes, Initial Native Apple Silicon Support as of v2.2.0 - [Release Notes](https://rogueamoeba.com/loopback/releasenotes.php) [Official Post](https://weblog.rogueamoeba.com/2020/11/16/rogue-amoeba-software-updates-for-macos-11-big-sur-and-m1-chip-based-macs/)
|
||||
* [NewTek NDI Connect](https://www.newtek.com/ndi/applications/connect/) - 🚫 No, not yet supported only works on Intel-based Macs - [Discussion #1](https://forums.newtek.com/threads/mac-m1-chipset-ndi-tools-support.163871/) [OBS Issue](https://github.com/Palakis/obs-ndi/issues/590)
|
||||
* [OBS](https://obsproject.com/) - ✳️ Yes, works via Rosetta 2 - [MacRumors Discussion](https://forums.macrumors.com/threads/so-hows-m1-for-streamers-obs-streamlabs-obs-etc.2269239/) [Mention in Issue](https://github.com/obsproject/obs-studio/pull/3444#issuecomment-690216403)
|
||||
* [Pioneer CDJ/XDJ Aggregator tool](https://support.pioneerdj.com/hc/en-us/articles/900002589966-CDJ-XDJ-Aggregator-Tool-for-Mac) - ✳️ Yes, works via Rosetta 2 - [Report](https://forums.pioneerdj.com/hc/en-us/community/posts/900003069263-How-to-tell-which-software-and-products-are-Apple-Silicon-Native-vs-translated-with-Rosetta-2?page=1#community_comment_900001461686)
|
||||
* [Pioneer DJS-1000 DJS-TSP Project Creator](https://support.pioneerdj.com/hc/en-us/articles/360038536691-DJS-1000-DJS-TSP-Project-Creator-For-MAC) - ✳️ Yes, works via Rosetta 2 - [Report](https://forums.pioneerdj.com/hc/en-us/community/posts/900003069263-How-to-tell-which-software-and-products-are-Apple-Silicon-Native-vs-translated-with-Rosetta-2?page=1#community_comment_900001461686)
|
||||
* [Pioneer INTERFACE 2](https://support.pioneerdj.com/hc/en-us/sections/360007668331-INTERFACE-2) - ✳️ Yes, works via Rosetta 2 - [Report](https://forums.pioneerdj.com/hc/en-us/community/posts/900003069263-How-to-tell-which-software-and-products-are-Apple-Silicon-Native-vs-translated-with-Rosetta-2?page=1#community_comment_900001461686)
|
||||
* [Pioneer PRO DJ LINK BRIDGE](https://www.pioneerdj.com/en-us/product/software/pro-dj-link-bridge/software/overview/) - ✳️ Yes, works via Rosetta 2 - [Report](https://forums.pioneerdj.com/hc/en-us/community/posts/900003069263-How-to-tell-which-software-and-products-are-Apple-Silicon-Native-vs-translated-with-Rosetta-2?page=1#community_comment_900001461686)
|
||||
* [Pioneer RB-DMX1](https://www.pioneerdj.com/en-us/product/software/rb-dmx1/dmx-interface/overview/) - ✳️ Yes, works via Rosetta 2 - [Report](https://forums.pioneerdj.com/hc/en-us/community/posts/900003069263-How-to-tell-which-software-and-products-are-Apple-Silicon-Native-vs-translated-with-Rosetta-2?page=1#community_comment_900001461686)
|
||||
* [Pioneer RMX-1000 REMIXBOX](https://www.pioneerdj.com/en/support/software/effector/rmx-1000/) - ✳️ Yes, works via Rosetta 2 - [Report](https://forums.pioneerdj.com/hc/en-us/community/posts/900003069263-How-to-tell-which-software-and-products-are-Apple-Silicon-Native-vs-translated-with-Rosetta-2?page=1#community_comment_900001461686)
|
||||
* [Pioneer TORAIZ SP-16 DJS-TSP Project Creator](https://support.pioneerdj.com/hc/en-us/articles/360038537531-TORAIZ-SP-16-DJS-TSP-Project-Creator-For-MAC) - ✳️ Yes, works via Rosetta 2 - [Report](https://forums.pioneerdj.com/hc/en-us/community/posts/900003069263-How-to-tell-which-software-and-products-are-Apple-Silicon-Native-vs-translated-with-Rosetta-2?page=1#community_comment_900001461686)
|
||||
* [Pioneer TORAIZ SQUID Manager](https://support.pioneerdj.com/hc/en-us/articles/360038537451-TORAIZ-SQUID-Manager-for-Mac) - ✳️ Yes, works via Rosetta 2 - [Report](https://forums.pioneerdj.com/hc/en-us/community/posts/900003069263-How-to-tell-which-software-and-products-are-Apple-Silicon-Native-vs-translated-with-Rosetta-2?page=1#community_comment_900001461686)
|
||||
* [Pioneer USB Connection Driver](https://support.pioneerdj.com/hc/en-us/articles/360038536051-USB-Connection-Link-Export-driver-for-Mac) - ✳️ Yes, works via Rosetta 2 - [Report](https://forums.pioneerdj.com/hc/en-us/community/posts/900003069263-How-to-tell-which-software-and-products-are-Apple-Silicon-Native-vs-translated-with-Rosetta-2?page=1#community_comment_900001461686)
|
||||
* [ProPresenter](https://renewedvision.com/propresenter/#download) - ✅ Yes, Full Native Apple Silicon Support as of v7.4 - [Official Compatibilty Notes](https://support.renewedvision.com/hc/en-us/articles/360057548273-Big-Sur-Apple-Silicon-Compatibility) [NDI Compatibility](https://support.renewedvision.com/hc/en-us/articles/1500000361482-NDI-Compatibility-for-Apple-Silicon-Processors)
|
||||
* [rekordbox](https://rekordbox.com/en/download/) - ✳️ Yes, works via Rosetta 2 with native support currently in development - [Official Support List](https://www.pioneerdj.com/en-us/landing/support-for-macos-big-sur/) [Verification](https://github.com/ThatGuySam/doesitarm/issues/560#issue-805540415)
|
||||
* [Serato DJ Pro](https://serato.com/dj/pro/downloads/mac) - ✳️ Yes, works via Rosetta 2 translation - [Beta Download](https://serato.com/forum/area/740)
|
||||
* [Super 8 R2](https://www.native-instruments.com/en/products/komplete/synths/super-8/) - ⏹ No, not working at all but support is in development - [Official Status](https://support.native-instruments.com/hc/en-us/articles/360013515618-macOS-11-Big-Sur-Compatibility-News) [Official Post](https://support.native-instruments.com/hc/en-us/articles/360014683497)
|
||||
|
|
@ -323,7 +340,7 @@ Builds - [Java on M1 Benchmarks](https://docs.google.com/spreadsheets/d/1g4U7LAI
|
|||
* [Archicad](https://graphisoft.com/solutions/products/archicad) - ✳️ Yes, works via Rosetta 2 - [Graphisoft support update](https://helpcenter.graphisoft.com/knowledgebase/130674/) [Graphisoft Thread](https://archicad-talk.graphisoft.com/viewtopic.php?p=312614) [Reddit thread](https://www.reddit.com/r/ArchiCAD/comments/hsjs6l/archicad_and_macos_armtransition/) [Tudy's feedback](https://github.com/ThatGuySam/doesitarm/pull/189#issuecomment-742729489)
|
||||
* [AutoCAD](https://www.autodesk.com/products/autocad/overview?plc=ACDIST&term=1-YEAR&support=ADVANCED&quantity=1) - ✳️ Yes, works via Rosetta 2 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/499#issuecomment-754202196) [AutoDesk Forums](https://forums.autodesk.com/t5/autocad-for-mac-forum/apple-silicon/m-p/9652836)
|
||||
* [CADintosh](https://www.lemkesoft.de/en/products/cadintosh/download/) - ✅ Yes, Full Native Apple Silicon Support - [🧪 Apple Silicon App Tested](https://doesitarm.com/apple-silicon-app-test/)
|
||||
* [PrusaSlicer](https://www.prusa3d.com/prusaslicer/) - ✳️ Yes, works via Rosetta 2 with native support in development - [Verification](https://github.com/ThatGuySam/doesitarm/issues/379#issue-755576203)
|
||||
* [PrusaSlicer](https://www.prusa3d.com/prusaslicer/) - ✅ Yes, Full Native Apple Silicon Support as of v2.3.1 - [Release Notes](https://github.com/prusa3d/PrusaSlicer/releases/tag/version_2.3.1)
|
||||
* [Rhinoceros 3D](https://www.rhino3d.com/download/) - 🚫 No, not yet supported only works on Intel-based Macs - [Developer Article](https://discourse.mcneel.com/t/apple-silicon-and-rhino-for-mac-the-work-continues/113164)
|
||||
* [Shaper3D](https://www.shapr3d.com/) - ✅ Yes, it was shown at the November 10th event - [Apple Nov 10 Event](https://youtu.be/5AwdkGKmZ0I?t=2211)
|
||||
* [SketchUp](https://www.sketchup.com/) - ✳️ Yes, works via Rosetta 2 - [Discussion](https://forums.sketchup.com/t/the-new-m1-processor/141946)
|
||||
|
|
@ -514,6 +531,7 @@ Builds - [Java on M1 Benchmarks](https://docs.google.com/spreadsheets/d/1g4U7LAI
|
|||
* [RetroArch](https://www.retroarch.com/?page=platforms) - ✳️ Yes, works via Rosetta 2 with native support in development - [Verification](https://github.com/ThatGuySam/doesitarm/issues/348)
|
||||
* [Rottenwood](https://software.charliemonroe.net/rottenwood/) - ✅ Yes, Full Native Apple Silicon Support - [Developer Article](http://blog.charliemonroe.net/big-sur-and-apple-silicon/)
|
||||
* [Shazam](https://apps.apple.com/app/shazam/id897118787?mt=12) - ✳️ Yes, works via Rosetta 2 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/582#issue-816739441)
|
||||
* [Snap Camera](https://snapcamera.snapchat.com/download/) - ✅ Yes, Full Native Apple Silicon Support - [Verification](https://github.com/ThatGuySam/doesitarm/issues/627#issue-860435755) [Supported Hardware](https://snapcamera.snapchat.com/download/)
|
||||
* [Spotify](https://www.spotify.com/us/download/mac/) - ✳️ Yes, works via Rosetta 2 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/172)
|
||||
* [Steam](https://store.steampowered.com/about/) - ✳️ Yes, reported working via Rosetta 2 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/153)
|
||||
* [Tidal](https://tidal.com/download) - ✳️ Yes, working via Rosetta 2 but with occasional force quits as of 2.23.0.488 - [GitHub issue](https://github.com/ThatGuySam/doesitarm/issues/314)
|
||||
|
|
@ -521,6 +539,7 @@ Builds - [Java on M1 Benchmarks](https://docs.google.com/spreadsheets/d/1g4U7LAI
|
|||
* [UU Booster](https://uu.163.com/down/mac/) - ✅ Yes, Full Native Apple Silicon Support - [Verification](https://github.com/ThatGuySam/doesitarm/issues/464#issue-771607189)
|
||||
* [Vienna](https://github.com/ViennaRSS/vienna-rss/releases/latest) - ✅ Yes, Full Native Apple Silicon Support as of v3.6 - [Release Notes](https://github.com/ViennaRSS/vienna-rss/releases/tag/v/3.6.0)
|
||||
* [VLC](https://www.videolan.org/vlc/download-macosx.html) - ✅ Yes, Full Native Apple Silicon Support as of v3.0.12 - [Release Notes](https://www.videolan.org/news.html#news-2021-01-12)
|
||||
* [Xbox Game Pass for PC](https://www.xbox.com/en-US/xbox-game-pass/pc-games) - ✳️ Yes, works via Parallels virtualization - [Download Parallels](https://prf.hn/l/6qOdLPB)
|
||||
* [Zwift](https://www.zwift.com/eu-de/download) - ✳️ Yes, works via Rosetta 2 as of v1.0 (25) - [Source](https://forums.zwift.com/t/m1-apple-silicon-compatibility/514491/81) [Verification](https://raw.githubusercontent.com/steve1878/images_does_it_arm/main/zwift_1.0_25.png)
|
||||
|
||||
|
||||
|
|
@ -595,6 +614,7 @@ Builds - [Java on M1 Benchmarks](https://docs.google.com/spreadsheets/d/1g4U7LAI
|
|||
* [AnyTrans](https://www.imobie.com/anytrans/download.htm) - ✳️ Yes, works via Rosetta 2 translation - [Article](https://setapp.sjv.io/apple-silicon-supported-apps) [View on Setapp](https://setapp.sjv.io/anytrans)
|
||||
* [AppCleaner](https://freemacsoft.net/appcleaner/) - ✅ Yes, Full Native Apple Silicon Support - [Verification](https://github.com/ThatGuySam/doesitarm/issues/559#issue-803995485)
|
||||
* [Archiver App](https://archiverapp.com/) - ✳️ Yes, works via Rosetta 2 translation - [Article](https://setapp.sjv.io/apple-silicon-supported-apps) [View on Setapp](https://setapp.sjv.io/archiver)
|
||||
* [AVTouchBar](https://www.avtouchbar.com/) - ✅ Yes, Full Native Apple Silicon Support as of v3.0.6 - [🧪 Apple Silicon App Tested](https://doesitarm.com/apple-silicon-app-test/)
|
||||
* [Backblaze](https://www.backblaze.com/) - ✅ Yes, Full Native Apple Silicon Support as of v7.0.2.494 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/409#issuecomment-821298155)
|
||||
* [balenaEtcher](https://github.com/balena-io/etcher/releases) - ✳️ Yes, works via Rosetta 2 - [Verification](https://github.com/ThatGuySam/doesitarm/issues/294#issuecomment-737011519)
|
||||
* [Bartender](https://www.macbartender.com/) - ✅ Yes, fully supported as of v4.0.20 - [Blog](https://www.macbartender.com/b4blog/Apple-Silicon-Support/) [View on Setapp](https://setapp.sjv.io/c/2708043/443665/5114)
|
||||
|
|
@ -671,6 +691,8 @@ Builds - [Java on M1 Benchmarks](https://docs.google.com/spreadsheets/d/1g4U7LAI
|
|||
* [Is Apple silicon ready?](https://isapplesiliconready.com/) - Great list with detailed app status
|
||||
* [Apple Silicon Games](https://applesilicongames.com/) - List of reported Games support including performance info.
|
||||
* [SweetWater Compatibility Guide](https://www.sweetwater.com/sweetcare/articles/macos-11-big-sur-compatibility-guide/) - Big Sur and Apple Silicon reports for producstion and live performance software
|
||||
* [Toolfarm Apple Silicon Compatibility](https://www.toolfarm.com/news/apple-silicon-compatibility/) - Product Compatibility for Apple M1 Silicon Macs
|
||||
* [Toolfarm Big Sur Compatibility](https://www.toolfarm.com/news/apple-silicon-compatibility/) - Product Compatibility for macOS Big Sur
|
||||
* [Ported2M1](https://ported2m1.com/) - Beautiful list with app support discussion
|
||||
* [MacRumors List](https://forums.macrumors.com/threads/universal-and-native-apple-silicon-apps.2267176/) - List of Universal and Native Apple Silicon Apps
|
||||
* [RoaringApps](https://roaringapps.com/collections/list-of-apple-silicon-native-apps) - List of apps ready for Apple Silicon M1 chip Macs
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ html {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Here you would add any custom utilities you need that don't come out of the
|
||||
* box with Tailwind.
|
||||
|
|
@ -160,3 +159,19 @@ html {
|
|||
background-position: -100% 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
button:focus .parent-focus\:visible,
|
||||
button:active .parent-focus\:visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
button:focus .parent-focus\:hidden,
|
||||
button:active .parent-focus\:hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.target\:visible:target {
|
||||
display: block;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import buildAppList from './helpers/build-app-list.js'
|
|||
import buildGamesList from './helpers/build-game-list.js'
|
||||
import buildHomebrewList from './helpers/build-homebrew-list.js'
|
||||
import buildVideoList from './helpers/build-video-list.js'
|
||||
import buildDeviceList from './helpers/build-device-list.js'
|
||||
|
||||
import { videosRelatedToApp } from './helpers/related.js'
|
||||
import { buildVideoPayload, buildAppBenchmarkPayload } from './helpers/build-payload.js'
|
||||
|
|
@ -14,6 +15,7 @@ import {
|
|||
getAppType,
|
||||
getAppEndpoint,
|
||||
getVideoEndpoint,
|
||||
isVideo
|
||||
} from './helpers/app-derived.js'
|
||||
import { makeSearchableList } from './helpers/searchable-list.js'
|
||||
|
||||
|
|
@ -61,6 +63,11 @@ class BuildLists {
|
|||
path: '/static/homebrew-list.json',
|
||||
buildMethod: buildHomebrewList,
|
||||
},
|
||||
{
|
||||
name: 'device',
|
||||
path: '/static/device-list.json',
|
||||
buildMethod: buildDeviceList,
|
||||
},
|
||||
|
||||
// Secondary Derivative built lists
|
||||
// Always goes after initial lists
|
||||
|
|
@ -225,10 +232,10 @@ class BuildLists {
|
|||
|
||||
this.lists[listKey].forEach( app => {
|
||||
|
||||
const isVideo = (app.category === undefined)
|
||||
// const isVideo = (app.category === undefined)
|
||||
const appType = getAppType( app )
|
||||
|
||||
if ( isVideo ) {
|
||||
if ( isVideo( app ) ) {
|
||||
// this.endpointMaps.eleventy.add({
|
||||
// route: getVideoEndpoint(app),
|
||||
// payload: buildVideoPayload( app, this.allVideoAppsList, this.lists.video )
|
||||
|
|
@ -273,9 +280,14 @@ class BuildLists {
|
|||
relatedVideos
|
||||
} )
|
||||
|
||||
} else if ( appType === 'device' ) {
|
||||
// Add device endpoint
|
||||
// console.log('Added to nuxt endpoints', app.endpoint )
|
||||
this.endpointMaps.nuxt.set( app.endpoint , { listing: app } )
|
||||
|
||||
} else {
|
||||
// Add game or other endpoint
|
||||
// console.log('Added to nuxt endpoints', getAppEndpoint(app))
|
||||
// console.log('Added to nuxt endpoints', app.endpoint )
|
||||
this.endpointMaps.nuxt.set( getAppEndpoint(app), { app } )
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,49 +2,103 @@
|
|||
|
||||
<nav
|
||||
:class="[
|
||||
'fixed top-0 left-0 right-0 z-navbar',
|
||||
isOpen ? 'bg-blur' : ''
|
||||
'fixed top-0 left-0 right-0 flex z-navbar',
|
||||
'bg-gradient-to-bl from-dark to-darker bg-fixed'
|
||||
]"
|
||||
>
|
||||
<div class="max-w-7xl mx-auto px-4 lg:px-6">
|
||||
<div class="mobile-menu-container flex items-center lg:hidden p-2">
|
||||
|
||||
<!-- Mobile menu button -->
|
||||
<a
|
||||
:class="[
|
||||
'mobile-menu-toggle rounded-md p-2',
|
||||
'inline-flex items-center justify-center',
|
||||
'text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:bg-gray-700 focus:text-white',
|
||||
'transition duration-150 ease-in-out'
|
||||
]"
|
||||
href="#mobile-menu"
|
||||
aria-label="Main menu"
|
||||
>
|
||||
<!-- Icon when menu is closed. -->
|
||||
<svg
|
||||
class="parent-focus:hidden h-6 w-6"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 6h16M4 12h16M4 18h16" />
|
||||
</svg>
|
||||
<!-- Icon when menu is open. -->
|
||||
<svg
|
||||
class="hidden parent-focus:visible h-6 w-6"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
id="mobile-menu"
|
||||
:class="[
|
||||
'mobile-menu hidden target:visible lg:hidden absolute bg-blur top-0 left-0 right-0 w-full py-3 px-2',
|
||||
]"
|
||||
>
|
||||
<!-- Mobile menu button -->
|
||||
<a
|
||||
:class="[
|
||||
'mobile-menu-close rounded-md p-2',
|
||||
'inline-flex items-center justify-center',
|
||||
'text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:bg-gray-700 focus:text-white',
|
||||
'transition duration-150 ease-in-out'
|
||||
]"
|
||||
href="#"
|
||||
aria-label="Main menu"
|
||||
>
|
||||
<!-- Icon when menu is open. -->
|
||||
<svg
|
||||
class="h-6 w-6"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<div class="px-2 pt-2 pb-3 lg:px-3">
|
||||
<a
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
:href="item.url"
|
||||
:class="[
|
||||
'mt-1 block px-3 py-2 rounded-md text-base font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700 transition duration-150 ease-in-out',
|
||||
($nuxt.$route.path === item.url) ? 'text-white bg-gray-900 hover:text-white' : 'text-gray-300 hover:bg-gray-700'
|
||||
]"
|
||||
>
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<div class="reponsive-menu-container relative w-full max-w-7xl mx-auto lg:px-6">
|
||||
<div class="flex justify-between h-16">
|
||||
<div class="flex">
|
||||
<div class="-ml-2 mr-2 flex items-center lg:hidden">
|
||||
<!-- Mobile menu button -->
|
||||
<button
|
||||
:aria-expanded="isOpen ? 'true' : 'false'"
|
||||
class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:bg-gray-700 focus:text-white transition duration-150 ease-in-out"
|
||||
aria-label="Main menu"
|
||||
@click="isOpen = !isOpen"
|
||||
>
|
||||
<!-- Icon when menu is closed. -->
|
||||
<svg
|
||||
v-if="!isOpen"
|
||||
class="h-6 w-6"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 6h16M4 12h16M4 18h16" />
|
||||
</svg>
|
||||
<!-- Icon when menu is open. -->
|
||||
<svg
|
||||
v-if="isOpen"
|
||||
class="h-6 w-6"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex-shrink-0 flex items-center text-4xl lg:text-5xl py-3">
|
||||
<div>🦾</div>
|
||||
</div>
|
||||
|
|
@ -103,27 +157,6 @@
|
|||
|
||||
Menu open: "block", Menu closed: "hidden"
|
||||
-->
|
||||
<div
|
||||
:class="[
|
||||
'lg:hidden',
|
||||
isOpen ? 'block' : 'hidden'
|
||||
]"
|
||||
>
|
||||
<div class="px-2 pt-2 pb-3 lg:px-3">
|
||||
<a
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
:href="item.url"
|
||||
:class="[
|
||||
'mt-1 block px-3 py-2 rounded-md text-base font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700 transition duration-150 ease-in-out',
|
||||
($nuxt.$route.path === item.url) ? 'text-white bg-gray-900 hover:text-white' : 'text-gray-300 hover:bg-gray-700'
|
||||
]"
|
||||
>
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
</template>
|
||||
|
|
@ -147,6 +180,10 @@ export default {
|
|||
label: 'Categories',
|
||||
url: '/categories',
|
||||
},
|
||||
{
|
||||
label: 'Devices',
|
||||
url: '/devices',
|
||||
},
|
||||
{
|
||||
label: 'Benchmarks',
|
||||
url: '/benchmarks',
|
||||
|
|
@ -166,10 +203,10 @@ export default {
|
|||
])
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
isOpen: false
|
||||
}
|
||||
}
|
||||
// data: function () {
|
||||
// return {
|
||||
// // isOpen: false
|
||||
// }
|
||||
// }
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@
|
|||
<input
|
||||
id="search"
|
||||
ref="search"
|
||||
:autofocus="autofocus"
|
||||
v-model="query"
|
||||
aria-label="Type here to Search"
|
||||
class="appearance-none w-full text-white font-hairline sm:text-5xl outline-none bg-transparent p-3"
|
||||
type="search"
|
||||
placeholder="Type to Search"
|
||||
autofocus
|
||||
autocomplete="off"
|
||||
@keyup="queryResults(query); scrollInputToTop()"
|
||||
>
|
||||
|
|
@ -222,6 +222,10 @@ export default {
|
|||
type: Number,
|
||||
default: null
|
||||
},
|
||||
autofocus: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
quickButtons: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
// App Data that is derived from other app data
|
||||
|
||||
export function isDevice ( listing ) {
|
||||
if ( !listing.hasOwnProperty('endpoint') ) return false
|
||||
|
||||
return listing.endpoint.startsWith('/device/')
|
||||
}
|
||||
|
||||
export function isVideo ( app ) {
|
||||
return app.hasOwnProperty('thumbnail') && app.hasOwnProperty('timestamps')
|
||||
|
|
@ -13,6 +18,10 @@ export function getAppType ( app ) {
|
|||
return 'video'
|
||||
}
|
||||
|
||||
if ( isDevice( app ) ) {
|
||||
return 'device'
|
||||
}
|
||||
|
||||
if(app.category !== Object(app.category)) {
|
||||
console.warn('app has no categories', app)
|
||||
|
||||
|
|
|
|||
|
|
@ -581,7 +581,7 @@ export default class AppFilesScanner {
|
|||
} )
|
||||
})
|
||||
|
||||
const scanTimeoutSeconds = 30
|
||||
const scanTimeoutSeconds = 60
|
||||
|
||||
// Scan for archives
|
||||
await Promise.all( this.files.map( ( file, scanIndex ) => {
|
||||
|
|
|
|||
77
helpers/app-store/genres.js
Normal file
77
helpers/app-store/genres.js
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
// Source 1: https://42matters.com/docs/app-market-data/ios/apps/appstore-genres
|
||||
export default {
|
||||
'0': ['Mobile Software Application'],
|
||||
'6018': ['Book'],
|
||||
'6000': ['Business'],
|
||||
'6022': ['Catalogs'],
|
||||
'6017': ['Education'],
|
||||
'6016': ['Entertainment'],
|
||||
'6015': ['Finance'],
|
||||
'6023': ['Food & Drink'],
|
||||
'6014': ['Games'],
|
||||
'7001': ['Games', 'Action'],
|
||||
'7002': ['Games', 'Adventure'],
|
||||
'7003': ['Games', 'Arcade'],
|
||||
'7004': ['Games', 'Board'],
|
||||
'7005': ['Games', 'Card'],
|
||||
'7006': ['Games', 'Casino'],
|
||||
'7007': ['Games', 'Dice'],
|
||||
'7008': ['Games', 'Educational'],
|
||||
'7009': ['Games', 'Family'],
|
||||
'7011': ['Games', 'Music'],
|
||||
'7012': ['Games', 'Puzzle'],
|
||||
'7013': ['Games', 'Racing'],
|
||||
'7014': ['Games', 'Role Playing'],
|
||||
'7015': ['Games', 'Simulation'],
|
||||
'7016': ['Games', 'Sports'],
|
||||
'7017': ['Games', 'Strategy'],
|
||||
'7018': ['Games', 'Trivia'],
|
||||
'7019': ['Games', 'Word'],
|
||||
'6013': ['Health & Fitness'],
|
||||
'6012': ['Lifestyle'],
|
||||
'6020': ['Medical'],
|
||||
'6011': ['Music'],
|
||||
'6010': ['Navigation'],
|
||||
'6009': ['News'],
|
||||
'6021': ['Newsstand'],
|
||||
'6008': ['Photo & Video'],
|
||||
'6007': ['Productivity'],
|
||||
'6006': ['Reference'],
|
||||
'6024': ['Shopping'],
|
||||
'6005': ['Social Networking'],
|
||||
'6004': ['Sports'],
|
||||
'6025': ['Stickers'],
|
||||
'6003': ['Travel'],
|
||||
'6002': ['Utilities'],
|
||||
'6001': ['Weather'],
|
||||
'6026': ['Developer Tools'],
|
||||
'6027': ['Graphics & Design'],
|
||||
'13001': ['Newsstand', 'News & Politics'],
|
||||
'13002': ['Newsstand', 'Fashion & Style'],
|
||||
'13003': ['Newsstand', 'Home & Garden'],
|
||||
'13004': ['Newsstand', 'Outdoors & Nature'],
|
||||
'13005': ['Newsstand', 'Sports & Leisure'],
|
||||
'13006': ['Newsstand', 'Automotive'],
|
||||
'13007': ['Newsstand', 'Arts & Photography'],
|
||||
'13008': ['Newsstand', 'Brides & Weddings'],
|
||||
'13009': ['Newsstand', 'Business & Investing'],
|
||||
'13010': ['Newsstand', 'Children\'s Magazines'],
|
||||
'13011': ['Newsstand', 'Computers & Internet'],
|
||||
'13012': ['Newsstand', 'Cooking, Food & Drink'],
|
||||
'13013': ['Newsstand', 'Crafts & Hobbies'],
|
||||
'13014': ['Newsstand', 'Electronics & Audio'],
|
||||
'13015': ['Newsstand', 'Entertainment'],
|
||||
'13017': ['Newsstand', 'Health, Mind & Body'],
|
||||
'13018': ['Newsstand', 'History'],
|
||||
'13019': ['Newsstand', 'Literary Magazines & Journals'],
|
||||
'13020': ['Newsstand', 'Men\'s Interest'],
|
||||
'13021': ['Newsstand', 'Movies & Music'],
|
||||
'13023': ['Newsstand', 'Parenting & Family'],
|
||||
'13024': ['Newsstand', 'Pets'],
|
||||
'13025': ['Newsstand', 'Professional & Trade'],
|
||||
'13026': ['Newsstand', 'Regional News'],
|
||||
'13027': ['Newsstand', 'Science'],
|
||||
'13028': ['Newsstand', 'Teens'],
|
||||
'13029': ['Newsstand', 'Travel & Regional'],
|
||||
'13030': ['Newsstand', 'Women\'s Interest'],
|
||||
}
|
||||
|
|
@ -1,24 +1,19 @@
|
|||
|
||||
import { promises as fs } from 'fs'
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import slugify from 'slugify'
|
||||
import axios from 'axios'
|
||||
|
||||
import statuses, { getStatusName } from './statuses'
|
||||
import appStoreGenres from './app-store/genres.js'
|
||||
import { findCategoryForTagsSet } from './categories.js'
|
||||
import parseDate from './parse-date'
|
||||
import { eitherMatches } from './matching.js'
|
||||
import { getAppEndpoint } from './app-derived'
|
||||
import { makeSlug } from './slug.js'
|
||||
|
||||
|
||||
const md = new MarkdownIt()
|
||||
|
||||
|
||||
const makeSlug = name => slugify(name, {
|
||||
lower: true,
|
||||
strict: true
|
||||
})
|
||||
|
||||
|
||||
const getTokenLinks = function ( childTokens ) {
|
||||
|
||||
const tokenList = []
|
||||
|
|
@ -98,6 +93,41 @@ const lookForLastUpdated = function (app, commits) {
|
|||
return null
|
||||
}
|
||||
|
||||
// Fetch list of genres for each bundle
|
||||
async function fetchBundleGenres () {
|
||||
const genresJsonUrl = `${process.env.VFUNCTIONS_URL}/app-store/listings-sheet?fields=bundleId,genreIds`
|
||||
|
||||
return await axios.get( genresJsonUrl )
|
||||
.then( response => {
|
||||
return new Map( response.data.apps )
|
||||
})
|
||||
.catch(function (error) {
|
||||
// handle error
|
||||
console.warn('Error fetching bundle genres', error)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function generateTagsSetFromGenres( bundleId, bundleGenres ) {
|
||||
// If we don't have this bundleID
|
||||
// then return empty
|
||||
if ( !bundleGenres.has( bundleId ) ) return new Set()
|
||||
|
||||
const genres = new Set()
|
||||
|
||||
bundleGenres.get( bundleId ).split(',').forEach( genreId => {
|
||||
if ( !appStoreGenres.hasOwnProperty(genreId) ) {
|
||||
console.warn('Not known genre ID', genreId)
|
||||
}
|
||||
|
||||
appStoreGenres[genreId].forEach( genreName => {
|
||||
genres.add(genreName)
|
||||
})
|
||||
})
|
||||
|
||||
return genres
|
||||
}
|
||||
|
||||
|
||||
export default async function () {
|
||||
|
||||
|
|
@ -113,6 +143,7 @@ export default async function () {
|
|||
// Save commits to file just in case
|
||||
// await fs.writeFile('./commits-data.json', JSON.stringify(commits))
|
||||
|
||||
const bundleGenres = await fetchBundleGenres()
|
||||
|
||||
const scanListMap = new Map()
|
||||
|
||||
|
|
@ -154,10 +185,28 @@ export default async function () {
|
|||
href: 'https://doesitarm.com/apple-silicon-app-test/',
|
||||
})
|
||||
|
||||
// console.log('appScan', appScan)
|
||||
|
||||
const tags = generateTagsSetFromGenres( appScan.bundleIdentifier, bundleGenres )
|
||||
|
||||
// Move productivity tag to the end since it's a more generic tag
|
||||
if ( tags.has('Productivity') ) {
|
||||
tags.delete('Productivity')
|
||||
tags.add('Productivity')
|
||||
}
|
||||
|
||||
const foundCategory = findCategoryForTagsSet( tags )
|
||||
|
||||
const category = {
|
||||
label: foundCategory ? foundCategory.label : undefined,
|
||||
slug: foundCategory ? foundCategory.slug : 'uncategorized'
|
||||
}
|
||||
|
||||
// Add to scanned app list
|
||||
scanListMap.set( appSlug, {
|
||||
name: appName,
|
||||
aliases: appScan['aliases'],
|
||||
bundleId: appScan.bundleIdentifier,
|
||||
status: statusName,
|
||||
lastUpdated: parseDate( appScan['Date'] ),
|
||||
// url,
|
||||
|
|
@ -169,9 +218,8 @@ export default async function () {
|
|||
},
|
||||
slug: appSlug
|
||||
}),
|
||||
category: {
|
||||
slug: 'uncategorized'
|
||||
},
|
||||
category,
|
||||
tags: Array.from(tags),
|
||||
relatedLinks
|
||||
})
|
||||
})
|
||||
|
|
@ -221,10 +269,7 @@ export default async function () {
|
|||
|
||||
if (isHeading && token.type === 'inline') {
|
||||
categoryTitle = token.content
|
||||
categorySlug = slugify(token.content, {
|
||||
lower: true,
|
||||
strict: true
|
||||
})
|
||||
categorySlug = makeSlug( token.content )
|
||||
|
||||
// appList[categorySlug] = []
|
||||
}
|
||||
|
|
@ -236,14 +281,27 @@ export default async function () {
|
|||
|
||||
const [ name, url ] = link.substring(1, link.length-1).split('](')
|
||||
|
||||
let bundleId = null
|
||||
let tags = []
|
||||
|
||||
// Search for this app in the scanList and remove duplicates
|
||||
scanListMap.forEach( ( scannedApp, key ) => {
|
||||
|
||||
for ( const alias of scannedApp.aliases) {
|
||||
for ( const alias of scannedApp.aliases ) {
|
||||
// console.log( key, alias, name, eitherMatches(alias, name) )
|
||||
|
||||
if ( eitherMatches(alias, name) ) {
|
||||
console.log(`Removing ${alias} from scanned apps`)
|
||||
// If we don't have a bundleId yet
|
||||
// Set this app's bundleId
|
||||
if ( bundleId === null ) { bundleId = scannedApp.bundleId }
|
||||
|
||||
// Merge this scanned app's tags into the matching app
|
||||
tags = Array.from(new Set([
|
||||
...tags,
|
||||
...scannedApp.tags
|
||||
]))
|
||||
|
||||
console.log(`Merged ${alias} (${scannedApp.bundleId}) from scanned apps into ${name} from README`)
|
||||
scanListMap.delete( key )
|
||||
}
|
||||
}
|
||||
|
|
@ -285,15 +343,22 @@ export default async function () {
|
|||
appList.push({
|
||||
name,
|
||||
status,
|
||||
bundleId,
|
||||
lastUpdated,
|
||||
// url,
|
||||
text,
|
||||
slug: appSlug,
|
||||
endpoint,
|
||||
category,
|
||||
tags,
|
||||
// content: token.content,
|
||||
relatedLinks
|
||||
relatedLinks,
|
||||
})
|
||||
|
||||
|
||||
// if ( tags.length > 1 ) {
|
||||
// console.log('tags', name, bundleId, tags)
|
||||
// }
|
||||
}
|
||||
|
||||
// appList[categorySlug]
|
||||
|
|
|
|||
33
helpers/build-device-list.js
Normal file
33
helpers/build-device-list.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import axios from 'axios'
|
||||
|
||||
import { makeSlug } from './slug.js'
|
||||
|
||||
export function getDeviceEndpoint ( slug ) {
|
||||
return `/device/${ slug }`
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default async function () {
|
||||
|
||||
const devicesJsonUrl = `${process.env.VFUNCTIONS_URL}/api/devices`
|
||||
|
||||
const rawDeviceList = await axios.get(devicesJsonUrl)
|
||||
.then( response => {
|
||||
return response.data
|
||||
})
|
||||
.catch(function (error) {
|
||||
// handle error
|
||||
console.warn('Error fetching device list', error)
|
||||
})
|
||||
|
||||
return rawDeviceList.filter( device => ( device.enabled !== 'no' ) ).map( device => {
|
||||
const slug = makeSlug( device.name )
|
||||
|
||||
return {
|
||||
...device,
|
||||
slug,
|
||||
endpoint: getDeviceEndpoint( slug ),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
|
||||
import { promises as fs } from 'fs'
|
||||
import slugify from 'slugify'
|
||||
import axios from 'axios'
|
||||
|
||||
// import { statuses } from './build-app-list'
|
||||
import { getAppEndpoint } from './app-derived'
|
||||
import { makeSlug } from './slug.js'
|
||||
|
||||
|
||||
// console.log('process.env.GAMES_SOURCE', process.env.GAMES_SOURCE)
|
||||
|
|
@ -101,10 +99,7 @@ export default async function () {
|
|||
if (isPlayable(game) && statusesTranslations.hasOwnProperty(environmentName(game)) === false) continue
|
||||
|
||||
// Generate slug
|
||||
const slug = slugify(game.Games, {
|
||||
lower: true,
|
||||
strict: true
|
||||
})
|
||||
const slug = makeSlug( game.Games )
|
||||
|
||||
// Find index of game is list so far
|
||||
const gameIndex = gameList.findIndex(game => {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
|
||||
import slugify from 'slugify'
|
||||
import axios from 'axios'
|
||||
|
||||
import { fuzzyMatchesWholeWord } from './matching.js'
|
||||
import { byTimeThenNull } from './sort-list.js'
|
||||
import { getVideoEndpoint } from './app-derived.js'
|
||||
import parseDate from './parse-date'
|
||||
import { makeSlug } from './slug.js'
|
||||
|
||||
|
||||
const inTimestamps = ( name, video ) => {
|
||||
|
|
@ -150,10 +150,7 @@ export default async function ( applist ) {
|
|||
if (fetchedVideos[videoId].title === 'Deleted video') continue
|
||||
|
||||
// Build video slug
|
||||
const slug = slugify(`${fetchedVideos[videoId].title}-i-${videoId}`, {
|
||||
lower: true,
|
||||
strict: true
|
||||
})
|
||||
const slug = makeSlug( `${fetchedVideos[videoId].title}-i-${videoId}` )
|
||||
|
||||
const apps = []
|
||||
// Generate new tag set based on api data
|
||||
|
|
|
|||
|
|
@ -1,14 +1,36 @@
|
|||
// Universal JS imports only
|
||||
import slugify from 'slugify'
|
||||
|
||||
import { makeSlug } from './slug.js'
|
||||
|
||||
export function makeCategorySlug ( categoryName ) {
|
||||
return slugify(categoryName, {
|
||||
lower: true,
|
||||
strict: true
|
||||
})
|
||||
return makeSlug( categoryName )
|
||||
}
|
||||
|
||||
const categoryMap = new Map([
|
||||
[ 'Business', 2 ],
|
||||
[ 'Entertainment', 5 ],
|
||||
[ 'Finance', 2 ],
|
||||
[ 'Games', 100 ],
|
||||
[ 'Music', 6 ],
|
||||
[ 'Photo & Video', 7 ],
|
||||
[ 'Productivity', 2 ],
|
||||
[ 'Utilities', 12 ],
|
||||
[ 'Graphics & Design', 7 ],
|
||||
[ 'Developer Tools', 1 ],
|
||||
// [ 'Name', 1 ],
|
||||
])
|
||||
|
||||
|
||||
|
||||
// Maps App Store Genre to categort IDS
|
||||
export function getCategoryIdForGenre ( genreName ) {
|
||||
|
||||
// If we don't have this genre mapped
|
||||
// then return nothing
|
||||
if ( !categoryMap.has(genreName) ) return null
|
||||
|
||||
// return this category id mapped to this genre
|
||||
return categoryMap.get( genreName )
|
||||
}
|
||||
|
||||
// Contains all types of properies to keep data consistent
|
||||
export const categoryTemplate = {
|
||||
|
|
@ -108,13 +130,21 @@ export const categories = {
|
|||
},
|
||||
|
||||
'live-production-and-performance': {
|
||||
id: 10,
|
||||
id: 11,
|
||||
...categoryTemplate,
|
||||
label: 'Live Production and Performance',
|
||||
pluralLabel: 'Live Production and Performance Software',
|
||||
slug: 'live-production-and-performance',
|
||||
},
|
||||
|
||||
'system-tools': {
|
||||
id: 12,
|
||||
...categoryTemplate,
|
||||
label: 'System Tools',
|
||||
pluralLabel: 'System Tools',
|
||||
slug: 'system-tools',
|
||||
},
|
||||
|
||||
// Special Lists
|
||||
'games': {
|
||||
id: 100,
|
||||
|
|
@ -152,6 +182,8 @@ export const categories = {
|
|||
}
|
||||
|
||||
|
||||
export const categoriesById = Object.fromEntries( Object.entries( categories ).map( ([ key, category ]) => [category.id, { ...category, key } ] ) )
|
||||
|
||||
export function getAppCategory (app) {
|
||||
if (typeof app.category === 'undefined') {
|
||||
console.log('app', app)
|
||||
|
|
@ -174,3 +206,23 @@ export function getAppCategory (app) {
|
|||
|
||||
return categories[app.category.slug]
|
||||
}
|
||||
|
||||
|
||||
export function findCategoryForTagsSet ( tags ) {
|
||||
|
||||
for ( const tag of tags ) {
|
||||
const categoryIdForGenre = getCategoryIdForGenre( tag )
|
||||
|
||||
// Skip non-mapped genres
|
||||
if ( categoryIdForGenre === null ) continue
|
||||
|
||||
// const foundCategory = categoriesById[ categoryIdForGenre ]
|
||||
|
||||
// category.label = foundCategory.label
|
||||
// category.slug = foundCategory.slug
|
||||
|
||||
return categoriesById[ categoryIdForGenre ]
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
|
|
|||
37
helpers/devices.js
Normal file
37
helpers/devices.js
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
import { getStatusName } from './statuses.js'
|
||||
|
||||
|
||||
export const macAppleSiliconStatuses = new Set([
|
||||
'native',
|
||||
'rosetta'
|
||||
])
|
||||
|
||||
export function deviceSupportsApp ( device, app ) {
|
||||
|
||||
// const statuses = {
|
||||
// '✅': 'native',
|
||||
// '✳️': 'rosetta',
|
||||
// '⏹': 'no-in-progress',
|
||||
// '🚫': 'no',
|
||||
// '🔶': 'unreported',
|
||||
// }
|
||||
const appStatus = getStatusName( app.text )
|
||||
|
||||
if ( device.type === 'intel') {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if ( device.type === 'mac-apple-silicon') {
|
||||
|
||||
return macAppleSiliconStatuses.has( appStatus )
|
||||
}
|
||||
|
||||
// if ( device.type === 'ios') {
|
||||
|
||||
// return
|
||||
// }
|
||||
|
||||
return false
|
||||
}
|
||||
9
helpers/slug.js
Normal file
9
helpers/slug.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// Universal JS imports only
|
||||
import slugify from 'slugify'
|
||||
|
||||
export function makeSlug ( name ) {
|
||||
return slugify(name, {
|
||||
lower: true,
|
||||
strict: true
|
||||
})
|
||||
}
|
||||
|
|
@ -25,6 +25,13 @@
|
|||
status = 301
|
||||
|
||||
|
||||
# imac redirect
|
||||
[[redirects]]
|
||||
from = "/device/apple-silicon-imac"
|
||||
to = "/device/m1-imac/"
|
||||
status = 307
|
||||
|
||||
|
||||
# Category Redirects
|
||||
[[redirects]]
|
||||
from = "/kind/entertainment"
|
||||
|
|
|
|||
11
package-lock.json
generated
11
package-lock.json
generated
|
|
@ -13,6 +13,7 @@
|
|||
"@open-wc/webpack-import-meta-loader": "^0.4.7",
|
||||
"@zip.js/zip.js": "^2.2.6",
|
||||
"axios": "^0.21.0",
|
||||
"chance": "^1.1.7",
|
||||
"cross-env": "^5.2.0",
|
||||
"jsdom": "^16.4.0",
|
||||
"lazysizes": "^5.3.0-beta1",
|
||||
|
|
@ -4842,6 +4843,11 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/chance": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/chance/-/chance-1.1.7.tgz",
|
||||
"integrity": "sha512-bua/2cZEfzS6qPm0vi3JEvGNbriDLcMj9lKxCQOjUcCJRcyjA7umP0zZm6bKWWlBN04vA0L99QGH/CZQawr0eg=="
|
||||
},
|
||||
"node_modules/character-parser": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
|
||||
|
|
@ -29210,6 +29216,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"chance": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/chance/-/chance-1.1.7.tgz",
|
||||
"integrity": "sha512-bua/2cZEfzS6qPm0vi3JEvGNbriDLcMj9lKxCQOjUcCJRcyjA7umP0zZm6bKWWlBN04vA0L99QGH/CZQawr0eg=="
|
||||
},
|
||||
"character-parser": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
"@open-wc/webpack-import-meta-loader": "^0.4.7",
|
||||
"@zip.js/zip.js": "^2.2.6",
|
||||
"axios": "^0.21.0",
|
||||
"chance": "^1.1.7",
|
||||
"cross-env": "^5.2.0",
|
||||
"jsdom": "^16.4.0",
|
||||
"lazysizes": "^5.3.0-beta1",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import dotenv from 'dotenv'
|
|||
import config from '../nuxt.config.js'
|
||||
|
||||
import { getAppType } from '../helpers/app-derived.js'
|
||||
import { deviceSupportsApp } from '../helpers/devices.js'
|
||||
import { makeLastUpdatedFriendly } from '../helpers/parse-date'
|
||||
|
||||
|
||||
|
|
@ -84,10 +85,24 @@ export class AppTemplate {
|
|||
|
||||
render( data ) {
|
||||
|
||||
const { app: { payload: { app, relatedVideos = [] } } } = data
|
||||
const {
|
||||
app: { payload: { app, relatedVideos = [] } },
|
||||
'device-list': deviceList
|
||||
} = data
|
||||
|
||||
// console.log('deviceList', deviceList)
|
||||
|
||||
// console.log('video.payload', Object.keys(video.payload))
|
||||
|
||||
const appDeviceSupport = deviceList.map( device => {
|
||||
const supportsApp = deviceSupportsApp( device, app )
|
||||
return {
|
||||
...device,
|
||||
emoji: supportsApp ? '✅' : '🚫',
|
||||
ariaLabel: `${app.name} has ${ supportsApp ? '' : 'not' } been reported to work on ${device.name}`
|
||||
}
|
||||
})
|
||||
|
||||
const lastUpdatedFriendly = makeLastUpdatedFriendly( app.lastUpdated )
|
||||
|
||||
const relatedLinksHtml = renderPageLinksHtml( app.relatedLinks )
|
||||
|
|
@ -109,6 +124,24 @@ export class AppTemplate {
|
|||
<div class="links space-y-6 sm:space-x-6 mb-8">
|
||||
${ relatedLinksHtml }
|
||||
</div>
|
||||
|
||||
<div class="device-support w-full">
|
||||
<h2 class="subtitle text-xl md:text-2xl font-bold mb-3">
|
||||
Device Support
|
||||
</h2>
|
||||
<div class="device-support-apps overflow-x-auto overflow-y-visible md:whitespace-no-wrap py-2 space-x-2 space-y-3">
|
||||
|
||||
${ appDeviceSupport.map( device => /* html */`
|
||||
<a
|
||||
href="${ device.endpoint }"
|
||||
role="button"
|
||||
class="relative inline-flex items-center leading-5 font-bold text-white border border-transparent focus:outline-none focus:border-indigo-600 neumorphic-shadow-inner bg-darker hover:bg-indigo-400 active:bg-indigo-600 transition duration-150 ease-in-out text-xs rounded-lg px-4 py-2"
|
||||
aria-label="${ device.ariaLabel }"
|
||||
>${ device.emoji } ${ device.name }</a>
|
||||
`).join('') }
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${ relatedVideos.length > 0 ? /* html */`
|
||||
|
|
|
|||
225
pages/device/_slug.vue
Normal file
225
pages/device/_slug.vue
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
<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>
|
||||
|
||||
<div class="flex flex-col md:flex-row space-x-0 space-y-4 md:space-y-0 md:space-x-4">
|
||||
|
||||
<LinkButton
|
||||
:href="`https://github.com/ThatGuySam/doesitarm/issues?q=is%3Aissue+${query}`"
|
||||
class="text-xs"
|
||||
>
|
||||
Request an App with Github
|
||||
</LinkButton>
|
||||
|
||||
<LinkButton
|
||||
:href="`https://twitter.com/DoesItARM/status/1330027384041508865`"
|
||||
class="text-xs"
|
||||
>
|
||||
Request an App with Twitter
|
||||
</LinkButton>
|
||||
|
||||
<LinkButton
|
||||
:href="`/apple-silicon-app-test/`"
|
||||
class="text-xs"
|
||||
>
|
||||
Scan Your Own App
|
||||
</LinkButton>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Search from '~/components/search.vue'
|
||||
import LinkButton from '~/components/link-button.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
|
||||
},
|
||||
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>
|
||||
76
pages/devices.vue
Normal file
76
pages/devices.vue
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue