apps.tsx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import { sortBy as _sortBy } from "lodash"
  2. import downloadOnGooglePlay from "../public/badges/google-play.svg"
  3. import downloadOnAppStore from "../public/badges/app-store.svg"
  4. import { FormattedMessage, useIntl } from "react-intl"
  5. import Head from "next/head"
  6. import Image from "next/legacy/image"
  7. import AppHero from "../components/AppHero"
  8. import { withDefaultStaticProps } from "../utils/defaultStaticProps"
  9. import footer_festival from "../public/illustrations/footer_festival.png"
  10. import AppsGrid from "../components/AppsGrid"
  11. import TwoUpFeature from "../components/TwoUpFeature"
  12. import { apps as appsList } from "../data/apps"
  13. import Hero from "../components/Hero"
  14. import appsHeroDesktop from "../public/illustrations/apps_hero_desktop.png"
  15. import appsHeroMobile from "../public/illustrations/apps_hero_mobile.png"
  16. import ios_android_apps from "../public/illustrations/ios_android_apps.png"
  17. import Layout from "../components/Layout"
  18. import ProgressiveWebIcon from "../public/icons/progressive-web.svg?inline"
  19. import ApiGearIcon from "../public/icons/api-gear.svg?inline"
  20. const AppsPage = () => {
  21. const intl = useIntl()
  22. return (
  23. <Layout>
  24. <Hero desktopImage={appsHeroDesktop} mobileImage={appsHeroMobile}>
  25. <div className="app-intro">
  26. <div className="container">
  27. <div className="app-intro__hero">
  28. <div className="app-intro__hero__unit">
  29. <h1 className="h1 mb-5">
  30. <FormattedMessage id="apps.title" defaultMessage="Apps" />
  31. </h1>
  32. <p className="sh1">
  33. <FormattedMessage
  34. id="apps.lead"
  35. defaultMessage="The best way to get started with Mastodon is through our official apps for iOS and Android, but many third-party apps are also available below."
  36. />
  37. </p>
  38. </div>
  39. </div>
  40. </div>
  41. </div>
  42. </Hero>
  43. <div className="grid justify-center gap-x-gutter gap-y-16 pt-10 pb-8 text-center md:grid-cols-12 md:text-start">
  44. <div className="md:col-span-6 lg:col-span-5 xl:col-span-4 xl:col-start-2">
  45. <h2 className="h4 mb-4">
  46. <FormattedMessage
  47. id="ios_and_android.download"
  48. defaultMessage="Download the apps"
  49. />
  50. </h2>
  51. <div className="grid grid-cols-2 justify-center gap-gutter md:justify-start">
  52. <a href="https://apps.apple.com/us/app/mastodon-for-iphone/id1571998974">
  53. <Image
  54. src={downloadOnAppStore}
  55. alt="Download on the App Store"
  56. layout="responsive"
  57. />
  58. </a>
  59. <a href="https://play.google.com/store/apps/details?id=org.joinmastodon.android">
  60. <Image
  61. src={downloadOnGooglePlay}
  62. alt="Get it on Google Play"
  63. layout="responsive"
  64. />
  65. </a>
  66. </div>
  67. </div>
  68. <div className="md:col-span-6 md:-mt-16 lg:col-span-5 lg:col-start-7 lg:-mt-32 xl:-mt-80">
  69. <div className="mx-auto max-w-xs md:max-w-none">
  70. <Image
  71. src={ios_android_apps}
  72. alt="Screenshots of Mastodon on iOS and Android, showing an artist's profile, reblogging, and a poll"
  73. />
  74. </div>
  75. </div>
  76. </div>
  77. <TwoUpFeature
  78. features={[
  79. {
  80. Icon: ProgressiveWebIcon,
  81. title: (
  82. <FormattedMessage
  83. id="browse_apps.progressive_web_app"
  84. defaultMessage="Progressive web app"
  85. />
  86. ),
  87. copy: (
  88. <FormattedMessage
  89. id="browse_apps.you_can_use_it_from_desktop"
  90. defaultMessage="You can always use Mastodon from the browser on your desktop or phone! It can be added to your home screen and some browsers even support push notifications, just like a native app!"
  91. />
  92. ),
  93. cta: (
  94. <FormattedMessage
  95. id="browse_apps.pwa_feature.cta"
  96. defaultMessage="Join a server"
  97. />
  98. ),
  99. cta_link: "/servers",
  100. },
  101. {
  102. Icon: ApiGearIcon,
  103. title: (
  104. <FormattedMessage
  105. id="browse_apps.open_api"
  106. defaultMessage="Open API"
  107. />
  108. ),
  109. copy: (
  110. <FormattedMessage
  111. id="browse_apps.make_your_own"
  112. defaultMessage="Mastodon is open-source and has an elegant, well-documented API that is available to everyone. Make your own app, or use one of the many third-party apps made by other developers!"
  113. />
  114. ),
  115. cta: (
  116. <FormattedMessage
  117. id="browse_apps.api_docs"
  118. defaultMessage="API documentation"
  119. />
  120. ),
  121. cta_link: "https://docs.joinmastodon.org/client/intro/",
  122. },
  123. ]}
  124. />
  125. <AppsGrid apps={appsList} />
  126. <AppHero
  127. backgroundImage={footer_festival}
  128. backgroundImagePosition="left center"
  129. />
  130. <Head>
  131. <title>
  132. {`${intl.formatMessage({
  133. id: "browse_apps.page_title",
  134. defaultMessage: "Get an app for Mastodon",
  135. })} - Mastodon`}
  136. </title>
  137. <meta
  138. property="og:title"
  139. content={intl.formatMessage({
  140. id: "browse_apps.page_title",
  141. defaultMessage: "Get an app for Mastodon",
  142. })}
  143. />
  144. <meta
  145. name="description"
  146. content={intl.formatMessage({
  147. id: "browse_apps.page_description",
  148. defaultMessage:
  149. "Browse official and third-party apps for the decentralized social network Mastodon",
  150. })}
  151. />
  152. <meta
  153. property="og:description"
  154. content={intl.formatMessage({
  155. id: "browse_apps.page_description",
  156. defaultMessage:
  157. "Browse official and third-party apps for the decentralized social network Mastodon",
  158. })}
  159. />
  160. </Head>
  161. </Layout>
  162. )
  163. }
  164. export const getStaticProps = withDefaultStaticProps()
  165. export default AppsPage