Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Abonnement — David Larlet</title>
  13. <meta name="description" content="That all sounds great. However, as I mentioned, we love goodwill, and a lot of people wince when they hear “subscription.” The first thing that pops up in a user’s head are scammy companies that make cancellation a nightmare, like multi-level marketing schemes, gym memberships, and Adobe. The App Store prevents these shenanigans: you get a reminder email before renewal, and you can cancel within the Settings app in seconds. Whenever a company offers a subscription, I always try to buy it through the App Store.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f0f0ea">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f0f0ea">
  26. <!-- Documented, feel free to shoot an email. -->
  27. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  28. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  29. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <script>
  36. function toggleTheme(themeName) {
  37. document.documentElement.classList.toggle(
  38. 'forced-dark',
  39. themeName === 'dark'
  40. )
  41. document.documentElement.classList.toggle(
  42. 'forced-light',
  43. themeName === 'light'
  44. )
  45. }
  46. const selectedTheme = localStorage.getItem('theme')
  47. if (selectedTheme !== 'undefined') {
  48. toggleTheme(selectedTheme)
  49. }
  50. </script>
  51. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  52. <article>
  53. <header>
  54. <h1>Abonnement</h1>
  55. </header>
  56. <nav>
  57. <p class="center">
  58. <a rel="prev" href="/david/2021/06/05/" title="Publication précédente : Incarnation">← Précédent</a> •
  59. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  60. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-home"></use>
  61. </svg> Accueil</a>
  62. </p>
  63. </nav>
  64. <hr>
  65. <blockquote lang="en">
  66. <p>That all sounds great. However, as I mentioned, we love goodwill, and a lot of people wince when they hear “subscription.” The first thing that pops up in a user’s head are scammy companies that make cancellation a nightmare, like multi-level marketing schemes, gym memberships, and Adobe. The App Store prevents these shenanigans: you get a reminder email before renewal, and you can cancel within the <em>Settings</em> app in seconds. Whenever a company offers a subscription, I always try to buy it through the App Store.</p>
  67. <p>Some folks absolutely loathe subscriptions on <em>principle</em>, and <mark>will never rent something if they can own it</mark>. This is not unreasonable. Halide is like a camera, and while professionals are used to renting gear, most consumers own their camera.</p>
  68. <p><cite><em><a href="https://lux.camera/lux-year-4-doubling-down/">Lux Year 4: Doubling Down</a></em> (<a href="/david/cache/2021/0c45751cd69748ca779b1442b26ad6c3/">cache</a>)</cite></p>
  69. </blockquote>
  70. <p>Les créateurs de Halide (et Spectre) reviennent en détail sur leur stratégie, notamment financière, pour faire évoluer leur produit. J’utilise ces deux applications, aussi c’est d’autant plus intéressant de lire leurs doutes et leurs pistes vis à vis de cette évolution.</p>
  71. <p><em>Je ne crois pas avoir lu un seul retour de développeur d’application pour iOS qui ne se plaigne pas de l’AppStore.</em></p>
  72. <p>Ce n’est vraiment pas évident de trouver un moyen d’être rémunéré de manière stable et pérenne lorsqu’on vend un produit, surtout si on souhaite qu’il soit durable. Il y a des jours où j’aimerais me préoccuper de ces aspects là… et d’autres où je suis bien content de vendre ma «&nbsp;force de travail&nbsp;». C’est un choix de vie qui m’offre pour l’instant une plus grande liberté d’esprit mais qui pourrait changer lorsque je n’aurai plus l’impression d’avoir suffisamment de <q>force</q> justement.</p>
  73. <p>En tant que développeur, j’ai de plus en plus l’impression que l’on crée notre propre système d’abonnement en augmentant la complexité de nos outils et de notre <em>stack</em> (ça sonne toujours mieux en anglais), ce qui génère la nécessité d’une maintenance régulière assurant un fond de roulement. La «&nbsp;tierce maintenance applicative&nbsp;» n’est pas nouvelle mais elle me semble atteindre un tout autre niveau ces dernières années sur le Web.</p>
  74. <p>On crée tranquillement notre propre besoin, <a href="http://megelison.com/poor-in-tech">en étant sur-payé·es</a> (<a href="/david/cache/2021/86eba8e465d7ce11ef61a0c61f878f21/">cache</a>), et personne ne semble s’en offusquer plus que ça…</p>
  75. <blockquote lang="en">
  76. <p>And I’m not 100% sure, but I think this might contribute to longevity. Some of my clients are still working with the same sites I built for them nearly 10&nbsp;years ago, a few with just minor security-related updates in the meantime and <mark>no other maintenance strictly required</mark>. That’s not to say that those sites couldn’t use a “lick of paint” to bring them in to the 2020s; the point is that they <em>work</em>. And for organizations working on really tight budgets, or budgets that fluctuate wildly due to public funding, stability is really important. They can’t afford a developer on retainer to keep things running smoothly.</p>
  77. <p><cite><em><a href="https://piperhaywood.com/two-articles-on-spa-or-spa-like-sites-vs-alternatives/">Two articles on SPA or SPA-like sites vs alternatives</a></em> (<a href="/david/cache/2021/d46752726e00de301573576176df1f1c/">cache</a>)</cite></p>
  78. </blockquote>
  79. <nav>
  80. <p class="center">
  81. <a rel="prev" href="/david/2021/06/05/" title="Publication précédente : Incarnation">← Précédent</a> •
  82. <a href="/david/2021/" title="Liste des publications récentes">↑ En 2021</a>
  83. </p>
  84. </nav>
  85. </article>
  86. <hr>
  87. <footer>
  88. <p>
  89. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  90. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-home"></use>
  91. </svg> Accueil</a> •
  92. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  93. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-rss2"></use>
  94. </svg> Suivre</a> •
  95. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  96. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-user-tie"></use>
  97. </svg> Pro</a> •
  98. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  99. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-mail"></use>
  100. </svg> Email</a> •
  101. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  102. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-hammer2"></use>
  103. </svg> Légal</abbr>
  104. </p>
  105. <template id="theme-selector">
  106. <form>
  107. <fieldset>
  108. <legend><svg class="icon icon-brightness-contrast">
  109. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-brightness-contrast"></use>
  110. </svg> Thème</legend>
  111. <label>
  112. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  113. </label>
  114. <label>
  115. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  116. </label>
  117. <label>
  118. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  119. </label>
  120. </fieldset>
  121. </form>
  122. </template>
  123. </footer>
  124. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  125. <script>
  126. function loadThemeForm(templateName) {
  127. const themeSelectorTemplate = document.querySelector(templateName)
  128. const form = themeSelectorTemplate.content.firstElementChild
  129. themeSelectorTemplate.replaceWith(form)
  130. form.addEventListener('change', (e) => {
  131. const chosenColorScheme = e.target.value
  132. localStorage.setItem('theme', chosenColorScheme)
  133. toggleTheme(chosenColorScheme)
  134. })
  135. const selectedTheme = localStorage.getItem('theme')
  136. if (selectedTheme && selectedTheme !== 'undefined') {
  137. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  138. }
  139. }
  140. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  141. window.addEventListener('load', () => {
  142. let hasDarkRules = false
  143. for (const styleSheet of Array.from(document.styleSheets)) {
  144. let mediaRules = []
  145. for (const cssRule of styleSheet.cssRules) {
  146. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  147. continue
  148. }
  149. // WARNING: Safari does not have/supports `conditionText`.
  150. if (cssRule.conditionText) {
  151. if (cssRule.conditionText !== prefersColorSchemeDark) {
  152. continue
  153. }
  154. } else {
  155. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  156. continue
  157. }
  158. }
  159. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  160. }
  161. // WARNING: do not try to insert a Rule to a styleSheet you are
  162. // currently iterating on, otherwise the browser will be stuck
  163. // in a infinite loop…
  164. for (const mediaRule of mediaRules) {
  165. styleSheet.insertRule(mediaRule.cssText)
  166. hasDarkRules = true
  167. }
  168. }
  169. if (hasDarkRules) {
  170. loadThemeForm('#theme-selector')
  171. }
  172. })
  173. </script>
  174. </body>
  175. </html>