Merge branch 'master' into develop

This commit is contained in:
Sam Carlton 2021-04-24 21:22:49 -05:00
commit 2176b0fabd
22 changed files with 831 additions and 114 deletions

2
.nvmrc
View file

@ -1 +1 @@
v15.11.0
v16.0.0

View file

@ -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 its 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

View file

@ -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;
}

View file

@ -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 } )
}

View file

@ -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>

View file

@ -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: () => [

View file

@ -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)

View file

@ -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 ) => {

View 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'],
}

View file

@ -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]

View 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 ),
}
})
}

View file

@ -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 => {

View file

@ -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

View file

@ -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
View 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
View file

@ -0,0 +1,9 @@
// Universal JS imports only
import slugify from 'slugify'
export function makeSlug ( name ) {
return slugify(name, {
lower: true,
strict: true
})
}

View file

@ -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
View file

@ -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",

View file

@ -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",

View file

@ -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
View 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
View 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>