<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  
  <title>Štěpán&#39;s Blog [EN]</title>
  <subtitle>English posts from my blog</subtitle>
  <link href="https://stepanzak.cc/feed.xml" rel="self" />
  <link href="https://stepanzak.cc/" />
  <updated>2026-06-21T22:00:00Z</updated>
  <id>https://stepanzak.cc/</id>
  <author>
    <name>Štěpán Žák</name>
  </author>
  <entry>
    <title>How I build a website for Frank</title>
    <link href="https://stepanzak.cc/blog/frantuv-web/" />
    <updated>2026-06-21T22:00:00Z</updated>
    <id>https://stepanzak.cc/blog/frantuv-web/</id>
    <content type="html">&lt;p&gt;My friend &lt;a href=&quot;https://instagram.com/franklys.t&quot;&gt;Frank&lt;/a&gt; is a digital artist. He uses Blender to create renders and animations, and they are pretty fucking cool.&lt;/p&gt;
&lt;p&gt;When I saw one of his instagram posts, I wanted to see all of the stuff he created so far.
I clicked on his profile, just to find out the only place I can see it all besides instagram is &lt;strong&gt;Pinterest&lt;/strong&gt;. &lt;span class=&quot;_shaking-text&quot;&gt;The horror!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dt4tzhayc/image/upload/v1771094695/pinterest_login_page.jpg&quot; alt=&quot;Phone screenshot of Pinterest forcing me to log in to view content&quot; title=&quot;holy enshittification&quot; width=&quot;150&quot;&gt;&lt;/p&gt;
&lt;p&gt;And I thought websites were invented to be viewed. Smh my head 🙄&lt;/p&gt;
&lt;p&gt;Well, this is why I, the great friend I am, decided to make him a &lt;strong&gt;real&lt;/strong&gt; website. And hoping he won&#39;t refuse this unsolicited gift of mine, I started building.&lt;/p&gt;

&lt;div class=&quot;callout&quot; data-callout=&quot;note&quot;&gt;
&lt;div class=&quot;callout-title&quot;&gt;
&lt;div class=&quot;callout-title-icon&quot;&gt;
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-pencil&quot;&gt;&lt;path d=&quot;M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m15 5 4 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt;
&lt;/div&gt;
&lt;div class=&quot;callout-title-inner&quot;&gt;Note&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;callout-content&quot;&gt;&lt;p&gt;Technical details follow. &lt;a href=&quot;https://stepanzak.cc/blog/frantuv-web/#final-result&quot;&gt;Skip to the final result&lt;/a&gt; if you don&#39;t care.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;h2&gt;How I did it&lt;/h2&gt;
&lt;p&gt;I used the &lt;a href=&quot;https://www.11ty.dev&quot;&gt;Eleventy&lt;/a&gt; static site generator, as that&#39;s also what &lt;a href=&quot;https://stepanzak.cc/colophon&quot;&gt;powers this website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have no idea what a static site generator is, you should probably skip this part.&lt;/p&gt;
&lt;h3&gt;The landing page&lt;/h3&gt;
&lt;p&gt;I didn&#39;t want anything special. Just a nice view of all the artworks. Basically Pinterest without all the Pinterest bullshit.&lt;/p&gt;
&lt;p&gt;First, I needed to add Frank&#39;s art. I could do it in many ways, but I wanted it to be relatively easy so he can do it himself when he creates something new. Luckily, Frank is friends with computers. He even uses EndeavourOS Linux (Arch, btw).&lt;/p&gt;
&lt;p&gt;I decided to use &lt;a href=&quot;https://cloudinary.com&quot;&gt;Cloudinary&lt;/a&gt; CDN to host the images and videos.&lt;/p&gt;
&lt;p&gt;I created a new file &lt;code&gt;content/_data/art-pieces.json&lt;/code&gt;. It looks like this:&lt;/p&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Terry the Terrier&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2025-11-07&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;desc&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Render of my animatronic Terry. My gf picked this name&quot;&lt;/span&gt;.&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;image&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;alt&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Animatronic Render&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;cloudinaryId&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;animatronic6_u2yxwe&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;736&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1308&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;...&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Adding a new art goes like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Upload it to Cloudinary&lt;/li&gt;
&lt;li&gt;Copy it&#39;s ID from cloudinary&lt;/li&gt;
&lt;li&gt;Create a new object in the json file&lt;/li&gt;
&lt;li&gt;Set cloudinaryId to the ID&lt;/li&gt;
&lt;li&gt;Set title, date, desc, type (image|video) and alt text&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;add-dimensions.js&lt;/code&gt; script to automatically add width and height.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Data from any json file inside the &lt;code&gt;_data/&lt;/code&gt; directory is accesible in all templates thanks to Eleventy.&lt;/p&gt;
&lt;p&gt;I used the &lt;a href=&quot;https://masonry.desandro.com/&quot;&gt;Masonry Layout library&lt;/a&gt; to implement a similar column layout as Pinterest does. The Masonry layout is &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Grid_layout/Masonry_layout&quot;&gt;coming to CSS natively&lt;/a&gt;, but is not yet supported by any major browser.&lt;/p&gt;
&lt;p&gt;Adding all the images from the json file was pretty trivial afterwards:&lt;/p&gt;
&lt;pre class=&quot;language-liquid&quot;&gt;&lt;code class=&quot;language-liquid&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;image-grid&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; piece &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; art&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;pieces &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;grid-piece&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; cloudinaryImg piece&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cloudinaryId &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;alt&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt;piece&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;alt&lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;230&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;grid-piece__title&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; piece&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;endfor&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(OK the real code is actually much more complex but this is how it works.)&lt;/p&gt;
&lt;p&gt;As you can see, our json data are accesible in the &lt;code&gt;art-pieces&lt;/code&gt; object. &lt;code&gt;cloudinaryImg&lt;/code&gt; is an ELeventy shortcode that takes the Cloudinary ID and returns an URL to the file.&lt;/p&gt;
&lt;p&gt;What immediately bugged me was the layout changes. My internet speed is quite bad, and every time one of the images finally loaded, the whole layout shifted.&lt;/p&gt;
&lt;p&gt;To solve that, the browser needs to know the dimensions of the images and videos when the library assembles them into the masonry layout - that is right after the page is loaded.
Easiest way to do so is just to add &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; keys inside &lt;code&gt;art-pieces.json&lt;/code&gt;.
Doing it manually would be really annoying though, so I wrote a small (78 lines) script that fetches the resources from Cloudinary and adds the dimensions automatically.&lt;/p&gt;
&lt;p&gt;I then added some more things like video duration and autoplay on mouse hover.&lt;/p&gt;
&lt;p&gt;Every art piece got wrapped in&lt;/p&gt;
&lt;pre class=&quot;language-liquid&quot;&gt;&lt;code class=&quot;language-liquid&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/art/&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; piece&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function filter&quot;&gt;slug&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which creates a valid url from it&#39;s title.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dt4tzhayc/image/upload/v1782415726/main-page-frantuvweb.png&quot; alt=&quot;Pinterest-like grid of various pictures and videos with titles&quot;&gt;&lt;/p&gt;
&lt;p&gt;Next step was creating a page for each art piece.&lt;/p&gt;
&lt;h3&gt;Individual art pages&lt;/h3&gt;
&lt;p&gt;Eleventy has this awesome feature called &lt;a href=&quot;https://www.11ty.dev/docs/pagination/&quot;&gt;Pagination&lt;/a&gt;.
That was the hardest part to wrap my head around, but I eventually did.&lt;/p&gt;
&lt;p&gt;I&#39;ll show you how it works.&lt;/p&gt;
&lt;p&gt;Frontmatter in &lt;code&gt;art-piece.liqid&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;pagination&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;art-pieces&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;piece&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;permalink&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/art/{{ piece.title | slug }}/&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This iterates over &lt;code&gt;art-pieces&lt;/code&gt;, and for each key it applies this template.
You can see that the value of &lt;code&gt;permalink&lt;/code&gt; key is actually also a template.
Due to that, the pagination creates a different page for each key.
And the permalink is created the same way as the links on the main page are.&lt;/p&gt;
&lt;p&gt;Inside this paginated template, I can then use the &lt;code&gt;piece&lt;/code&gt; object that refers to the current art piece form &lt;code&gt;art-pieces.json&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-liquid&quot;&gt;&lt;code class=&quot;language-liquid&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;art-section&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; cloudinaryImg piece&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cloudinaryId &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;alt&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt;piece&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;alt&lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;info-section&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; piece&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; piece&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token object&quot;&gt;date&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; piece&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;desc &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&quot;callout&quot; data-callout=&quot;note&quot;&gt;
&lt;div class=&quot;callout-title&quot;&gt;
&lt;div class=&quot;callout-title-icon&quot;&gt;
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; class=&quot;lucide lucide-pencil&quot;&gt;&lt;path d=&quot;M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m15 5 4 4&quot;&gt;&lt;/path&gt;&lt;/svg&gt;
&lt;/div&gt;
&lt;div class=&quot;callout-title-inner&quot;&gt;Note&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;callout-content&quot;&gt;&lt;p&gt;This is, again, heavily simplified to be easier to understand.
For example, there&#39;s no handling of videos in this example.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Another nice thing about Eleventy pagination is that you get &lt;em&gt;previous&lt;/em&gt; and &lt;em&gt;next&lt;/em&gt; links for free:&lt;/p&gt;
&lt;pre class=&quot;language-liquid&quot;&gt;&lt;code class=&quot;language-liquid&quot;&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; pagination&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;href&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;previous &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; pagination&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;href&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;previous &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function filter&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Previous&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; pagination&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;href&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;next &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt; pagination&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;href&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;next &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function filter&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Next&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token liquid language-liquid&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Art piece pages ended up looking like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dt4tzhayc/image/upload/v1782415885/frantuvweb-singleview.png&quot; alt=&quot;Video with title, date, description and Previous/Next buttons&quot; width=&quot;250&quot;&gt;&lt;/p&gt;
&lt;p&gt;Since it&#39;s a static website, comments have to be added using some third-party service.
I decided to leave that on Frank.&lt;/p&gt;
&lt;p&gt;I polished the website, added styles, meta tags, 404 page, and other uninteresting stuff.&lt;/p&gt;
&lt;h3&gt;Deployment&lt;/h3&gt;
&lt;p&gt;While I hate GitHub and use it only when really necessary, I still decided to go with it.&lt;/p&gt;
&lt;p&gt;Firstly, it&#39;s super easy to enable static site hosting on any repo, which then gets it&#39;s own &lt;code&gt;.github.io&lt;/code&gt; domain. GitHub actions can build the Eleventy website on each commit.&lt;/p&gt;
&lt;p&gt;Secondly, Frank can edit the json file directly from the web interface, and he&#39;s already familiar with GitHub.&lt;/p&gt;
&lt;p&gt;He doesn&#39;t have to care about the underlying technology at all. He uploads his art to Cloudinary, adds it into the json file from his browser without ever touching git, and the website magically updates.&lt;/p&gt;
&lt;p&gt;If you want to look at the source code, the whole repo is &lt;a href=&quot;https://github.com/franklyst/frankweb&quot;&gt;here&lt;/a&gt;. Leave a star while you&#39;re at it ;)&lt;/p&gt;
&lt;h2&gt;Final result&lt;/h2&gt;
&lt;p&gt;👉👉👉&lt;strong&gt;Visit the website &lt;a href=&quot;https://franklyst.github.io/frankweb/&quot;&gt;HERE&lt;/a&gt;!&lt;/strong&gt; 👈👈👈&lt;/p&gt;
&lt;p&gt;Or, if you are &lt;em&gt;really&lt;/em&gt; lazy, here&#39;s an embedded iframe:&lt;/p&gt;
&lt;iframe src=&quot;https://franklyst.github.io/frankweb/&quot; width=&quot;100%&quot; height=&quot;1000&quot; style=&quot;zoom: 0.6&quot; loading=&quot;lazy&quot;&gt;
&lt;/iframe&gt;</content>
  </entry>
  <entry>
    <title>Controlling a phone camera with a remote</title>
    <link href="https://stepanzak.cc/blog/phone-camera-remote-control/" />
    <updated>2026-02-13T23:00:00Z</updated>
    <id>https://stepanzak.cc/blog/phone-camera-remote-control/</id>
    <content type="html">&lt;p&gt;My grandpa asked me to help with a seemingly simple thing recently: he wanted to put his phone somewhere and then start/stop video recording with a remote he bought. The remote has two buttons: volume up and volume down.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dt4tzhayc/image/upload/v1771094695/ResizedImage_2026-02-14_19-42-07_8296_1.jpg&quot; alt=&quot;Small remote control with two buttons&quot; width=&quot;150&quot;&gt;&lt;/p&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;He has a Samsung phone, and Samsung&#39;s camera app, like most others, can be controlled with volume buttons.&lt;/p&gt;
&lt;p&gt;The issue is, they both do the same thing. You can start recording with either button, and the same goes for stopping recording.
He doesn&#39;t want to always keep the state of the phone in his head. If he forgot, he could think he is starting recording while he would, in fact, stop it.&lt;/p&gt;
&lt;p&gt;The solution is theoretically simple - make one of the buttons only start and the other only stop the recording. How do I do that, though?&lt;/p&gt;
&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;The solution was an app called &lt;a href=&quot;https://github.com/keymapperorg/KeyMapper&quot;&gt;KeyMapper&lt;/a&gt;, available on the Play Store and F-Droid. As the name suggests, it remaps keys. What surprised me was that it can tell the difference between the volume buttons on the phone and on the remote. Another great feature is remapping only for a specified app, Samsung Camera in this case.&lt;/p&gt;
&lt;p&gt;But what do you remap the buttons to to only start or stop recording? Well, here comes the best ability of KeyMapper - you can record yourself clicking on any button on your screen, and it will remember which button it was. &amp;quot;Start Recording&amp;quot;, in my case. Then, you just bind the remote&#39;s key to click on this very button. If there&#39;s no &amp;quot;Start Recording&amp;quot; button, as the camera is currently recording, nothing happens. Exactly what my grandpa wanted.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dt4tzhayc/image/upload/v1771094695/Screenshot_20260214-193008.png&quot; alt=&quot;KeyMapper screenshot. Group named Camera Remote. Trigger: Volume up (Any device) Actions: Tap: Start video. Trigger: Volume down (Any device): Actions: Tap: Stop video&quot; width=&quot;250&quot;&gt;&lt;/p&gt;
&lt;h2&gt;One Last Improvement&lt;/h2&gt;
&lt;p&gt;Remote controlling works like a charm, but there&#39;s an issue. The screen goes off when it&#39;s not recording after a while. And if you set the screen timeout to a really long time (although I&#39;m not sure what the maximum allowed is), the screen is going to drain the battery.&lt;/p&gt;
&lt;p&gt;If you are on Samsung, like my grandpa is, there&#39;s an app from Samsung for you. It&#39;s called Battery Guardian, from the &lt;em&gt;Good Guardians&lt;/em&gt; suite, and it has a little side feature that we&#39;re going to use:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Screen Curtain is a new feature that allows you to maintain application running status while the screen is turned off. Use Screen Curtain to minimize battery consumption and heat generation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Install Battery Guardian from the &lt;a href=&quot;http://apps.samsung.com/appquery/appDetail.as?appId=com.samsung.android.statsd&quot;&gt;Galaxy Store&lt;/a&gt;, or sideload from &lt;a href=&quot;https://www.apkmirror.com/apk/samsung-electronics-co-ltd/battery-guardian/&quot;&gt;APKMirror&lt;/a&gt; if you are in unsupported country. Enable Screen Curtain. It&#39;s just a few clicks, but &lt;a href=&quot;https://us.community.samsung.com/t5/Tips/One-UI-6-New-Feature-Screen-Curtain/td-p/2673709&quot;&gt;here&#39;s a guide&lt;/a&gt;.
When you start it from the quick panel button, your screen will go almost dark. Any app running will continue to run underneath, and the remote control will continue to work with our remaps. It also disables the screen timeout.&lt;/p&gt;
&lt;p&gt;If you don&#39;t have a Samsung phone, you&#39;ll have to find an alternative. Just be carefull what you install, since it will for sure require the accessibility permission, which is a dangerous one.&lt;/p&gt;
&lt;p&gt;Thanks for reading, I hope I helped you :)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Leaving rooted Android</title>
    <link href="https://stepanzak.cc/blog/leaving-rooted-android/" />
    <updated>2025-11-23T23:00:00Z</updated>
    <id>https://stepanzak.cc/blog/leaving-rooted-android/</id>
    <content type="html">&lt;p&gt;I&#39;ve got a new phone - a Pixel 7 Pro that someone broke, my grandpa bought cheaply and repaired. First thing I did was to install &lt;a href=&quot;https://grapheneos.org&quot;&gt;GrapheneOS&lt;/a&gt;. The biggest change about that switch is that GrapheneOS doesn&#39;t provide root access, and &lt;a href=&quot;https://www.reddit.com/r/GrapheneOS/comments/13264di/comment/ji54e19/&quot;&gt;apparently for a good reason&lt;/a&gt;.
In this blog post, I&#39;ll list every single tool I use that uses root privileges, to see what am I going to lose by switching to a non-rooted system.&lt;/p&gt;
&lt;h2&gt;KernelSU modules&lt;/h2&gt;
&lt;p&gt;There are two main ways of utilizing root access: Modules and Superuser apps.&lt;/p&gt;
&lt;p&gt;Superuser apps are regular android apps that you grant root access. Some of them require root access for a few features but work without it. Like a file manager that can browse restricted parts of the filesystem if granted root access.&lt;/p&gt;
&lt;p&gt;Root modules, on the other hand, are scripts specific to the root method you use - &lt;a href=&quot;https://github.com/KernelSU-Next/KernelSU-Next&quot;&gt;KernelSU Next&lt;/a&gt; in my case (but most people know &lt;a href=&quot;https://github.com/topjohnwu/Magisk&quot;&gt;Magisk&lt;/a&gt;). They usually do some deeper system changes, and aren&#39;t expected to have an UI (but some of them do).
Here are the modules I have installed at the time of preparing to switch to the new phone:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JamesDSP Manager
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/james34602/JamesDSPManager&quot;&gt;https://github.com/james34602/JamesDSPManager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Advanced audio processing engine&lt;/li&gt;
&lt;li&gt;I used it as an equalizer.&lt;/li&gt;
&lt;li&gt;Overkill running in background.&lt;/li&gt;
&lt;li&gt;I don&#39;t have great headphones and lossless music streaming, didn&#39;t notice a difference really.&lt;/li&gt;
&lt;li&gt;It broke and I didn&#39;t bother fixing it.&lt;/li&gt;
&lt;li&gt;there&#39;s a &lt;a href=&quot;https://github.com/ThePBone/RootlessJamesDSP&quot;&gt;rootless version&lt;/a&gt; with some limitations that are not dealbreakers for me&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ReZygisk
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/PerformanC/ReZygisk&quot;&gt;https://github.com/PerformanC/ReZygisk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Required mainly for LSPosed to work (see &lt;a href=&quot;https://stepanzak.cc/blog/leaving-rooted-android/#lsposed-modules&quot;&gt;LSPosed modules&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RVX YT Music, Youtube RVX LITE
&lt;ul&gt;
&lt;li&gt;RVX stands for &lt;a href=&quot;https://github.com/inotia00/revanced-patches&quot;&gt;ReVanced Extended&lt;/a&gt;, which is a modified version of the &lt;a href=&quot;https://revanced.app&quot;&gt;ReVanced&lt;/a&gt; patches.&lt;/li&gt;
&lt;li&gt;These allow you to patch various applications (YouTube and YouTube Music for me) to remove ads, unlock premium features and add various enhancements.&lt;/li&gt;
&lt;li&gt;I use root modules distributed through Telegram channel not affiliated with ReVanced or Revanced Extended 💀&lt;/li&gt;
&lt;li&gt;I use these just for the convenience, I can just compile ReVanced (Extended) APKs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;WiFi Password Viewer for MMRL
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mmrl.dev/repository/grdoglgmr/mmrl_wpd&quot;&gt;https://mmrl.dev/repository/grdoglgmr/mmrl_wpd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cool but I never actually used it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Zygisk - LSPosed
&lt;ul&gt;
&lt;li&gt;See &lt;a href=&quot;https://stepanzak.cc/blog/leaving-rooted-android/#lsposed-modules&quot;&gt;LSPosed modules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tricky Store OSS, PlayIntegrityFix-NEXT
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/EricInacio01/PlayIntegrityFix-NEXT&quot;&gt;https://github.com/EricInacio01/PlayIntegrityFix-NEXT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/beakthoven/TrickyStoreOSS/releases&quot;&gt;https://github.com/beakthoven/TrickyStoreOSS/releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;For Play Integrity, doesn&#39;t even work half the time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AshLooper - Boot Loop protection
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/RipperHybrid/AshLooper&quot;&gt;https://github.com/RipperHybrid/AshLooper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Disables root modules on bootloop - I won&#39;t need it when I won&#39;t have any root modules.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lightweight Exynos Undervolter (LEU)
&lt;ul&gt;
&lt;li&gt;It&#39;s supposed to improve battery life by &lt;a href=&quot;https://en.wikipedia.org/wiki/Dynamic_voltage_scaling#Undervolting&quot;&gt;undervolting&lt;/a&gt; the CPU.&lt;/li&gt;
&lt;li&gt;Only works on Samsung (Exynos chip).&lt;/li&gt;
&lt;li&gt;Didn&#39;t notice any difference using it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Zygisk - Sui
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/RikkaApps/Sui&quot;&gt;https://github.com/RikkaApps/Sui&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Like Shizuku but for giving root access&lt;/li&gt;
&lt;li&gt;Unmaintained, stopped displaying the list of apps 💀 (so I can&#39;t check or revoke their privileges)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Wow! It looks like I could do just fine without those modules. The only issue could be LSPosed, so let&#39;s see what do I use that for.&lt;/p&gt;
&lt;h2&gt;LSPosed modules&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/JingMatrix/LSPosed&quot;&gt;LSPosed&lt;/a&gt; (JingMatrix&#39;s fork) is a modern reimplementation of the Xposed framework. &lt;em&gt;Xposed is a framework for modules that can change the behavior of the system and apps without touching any APKs.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;For example: the ReVanced apps are traditionally modified by applying patches and compiling new patched APKs. LSPosed module could apply those same patches to regular apps installed from the Play Store, while not modyfiing them permanently. It can also hook multiple apps, for general patches like blocking screenshot detection.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Free Notifications
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/binarynoise/XposedModulets&quot;&gt;https://github.com/binarynoise/XposedModulets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Being able to disable some annoying persistent system notifications is great in theory.&lt;/li&gt;
&lt;li&gt;I remember using it only once, so not a big deal.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hide My Applist
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Dr-TSNG/Hide-My-Applist&quot;&gt;https://github.com/Dr-TSNG/Hide-My-Applist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Never needed it for any app, actually broke my banking app.&lt;/li&gt;
&lt;li&gt;Another app that went closed-source.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NoStorageRestrict
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Xposed-Modules-Repo/com.github.dan.nostoragerestrict&quot;&gt;https://github.com/Xposed-Modules-Repo/com.github.dan.nostoragerestrict&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Another nice freedom to have, but I&#39;ve never used it.&lt;/li&gt;
&lt;li&gt;The restrictions might be there for a reason actually.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AlternativeUnlockXposed
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/leohearts/AlternativeUnlockXposed&quot;&gt;https://github.com/leohearts/AlternativeUnlockXposed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Playing rickroll when &lt;em&gt;12345678&lt;/em&gt; password is entered is funny for like a week.&lt;/li&gt;
&lt;li&gt;I disabled it soon (LSPosed modules of course eat some battery).&lt;/li&gt;
&lt;li&gt;GrapheneOS has &lt;a href=&quot;https://grapheneos.org/features#duress&quot;&gt;it&#39;s own feature&lt;/a&gt; for duress password that wipes the device instead of unlocking it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CaptureSposed
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/99keshav99/CaptureSposed&quot;&gt;https://github.com/99keshav99/CaptureSposed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;This might be the most useful module from the list, but I personally never needed it&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;XPL-EX
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/0bbedCode/XPL-EX&quot;&gt;https://github.com/0bbedCode/XPL-EX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Never bothered to learn how to use it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;InstaEclipse
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ReSo7200/InstaEclipse&quot;&gt;https://github.com/ReSo7200/InstaEclipse&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Patches Instagram to remove ADs, disable reels, and add some privacy enhancements.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I need this.&lt;/li&gt;
&lt;li&gt;I hope I&#39;ll be able to make regular APKs with &lt;a href=&quot;https://github.com/JingMatrix/LSPatch&quot;&gt;LSPatch&lt;/a&gt; (JingMatrix&#39;s fork). &lt;strong&gt;EDIT:&lt;/strong&gt; Wile it&#39;s &lt;a href=&quot;https://github.com/ReSo7200/InstaEclipse/issues/100&quot;&gt;not possible&lt;/a&gt; to patch standalone Instagram APK with InstaEclipse embedded, it works with non-root LSPatch manager.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Re:Telegram
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Sakion-Team/Re-Telegram&quot;&gt;https://github.com/Sakion-Team/Re-Telegram&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Useful, but I don&#39;t use Telegram that much.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lucky Patcher
&lt;ul&gt;
&lt;li&gt;see Lucky Patcher in &lt;a href=&quot;https://stepanzak.cc/blog/leaving-rooted-android/#apps-with-superuser-rights&quot;&gt;Apps with Superuser rights&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Apps with Superuser rights&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Shizuku
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/RikkaApps/Shizuku&quot;&gt;https://github.com/RikkaApps/Shizuku&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Allows you to share &lt;a href=&quot;https://en.wikipedia.org/wiki/Android_Debug_Bridge&quot;&gt;ADB&lt;/a&gt; access with apps.&lt;/li&gt;
&lt;li&gt;ADB allows you to do some restricted stuff on Android, not as much as root though.&lt;/li&gt;
&lt;li&gt;Can be used without root, setting it up is annoying every time you need to use it.&lt;/li&gt;
&lt;li&gt;OK for something like &lt;em&gt;SD Maid SE&lt;/em&gt;, not for long running apps in the background, or things you need to do fast at the moment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Android USB Script, USB HID Client
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Netdex/android-usb-script&quot;&gt;https://github.com/Netdex/android-usb-script&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Arian04/android-hid-client&quot;&gt;https://github.com/Arian04/android-hid-client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Neither works on the kernel I used.&lt;/li&gt;
&lt;li&gt;Mostly a gimmick, not really that useful.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;App Manager
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/MuntashirAkon/AppManager&quot;&gt;https://github.com/MuntashirAkon/AppManager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;So many features
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;displays running apps&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;app backup (with data)&lt;/li&gt;
&lt;li&gt;app usage&lt;/li&gt;
&lt;li&gt;also has a debloater&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Very impressive app!&lt;/li&gt;
&lt;li&gt;10x better than the app manager in system settings.&lt;/li&gt;
&lt;li&gt;I will miss this app :(&lt;/li&gt;
&lt;li&gt;Some features will work without root, but probably not the most useful ones.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;FindMyDevice
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gitlab.com/fmd-foss/fmd-android&quot;&gt;https://gitlab.com/fmd-foss/fmd-android&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Most of the functionality should be grantable without root.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Material Files
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/zhanghai/MaterialFiles&quot;&gt;https://github.com/zhanghai/MaterialFiles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;My favorite file manager, even without root.&lt;/li&gt;
&lt;li&gt;With root, it can access all files on device (like files in app storage)&lt;/li&gt;
&lt;li&gt;Sometimes very useful:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://f.cz/@stepan/114145042723916307&quot;&gt;https://f.cz/@stepan/114145042723916307&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SD Maid SE
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/d4rken-org/sdmaid-se&quot;&gt;https://github.com/d4rken-org/sdmaid-se&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I use it only once in a while.&lt;/li&gt;
&lt;li&gt;Most advanced features can be enabled with Shizuku, no problem since I don&#39;t need to run it often.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tasker
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://tasker.joaoapps.com/&quot;&gt;https://tasker.joaoapps.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Some features won&#39;t work (quite a lot)&lt;/li&gt;
&lt;li&gt;It&#39;s a paid app. I bought it two years ago, and created like 2 tasks.&lt;/li&gt;
&lt;li&gt;One of those apps that feel extremely useful, but you don&#39;t really use them that much.&lt;/li&gt;
&lt;li&gt;One less app to run in the background.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Termux
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/termux/termux-app&quot;&gt;https://github.com/termux/termux-app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Theoretically can do &lt;a href=&quot;https://ivonblog.com/en-us/posts/termux-chroot-ubuntu/&quot;&gt;full linux distro chroot&lt;/a&gt; with root.
&lt;ul&gt;
&lt;li&gt;Full linux distro doesn&#39;t really bring much advantage over normal termux - In which I have tmux, neovim, python, node, even Zola SSG so I can live preview my website changes.&lt;/li&gt;
&lt;li&gt;Running full linux distro is harsh on system resources, eats up disk space, and drains battery. Total overkill.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lucky Patcher
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;https://luckypatchers.com/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Russian closed source app to patch apps and games, mainly to unlock paid content and get free coins/gems/whatever.&lt;/li&gt;
&lt;li&gt;Security concerns&lt;/li&gt;
&lt;li&gt;Unstable&lt;/li&gt;
&lt;li&gt;I&#39;m richer, so I don&#39;t need to crack apps that often.
&lt;ul&gt;
&lt;li&gt;I mean I&#39;m not rich, but I can pay $4 for a good app.&lt;/li&gt;
&lt;li&gt;Many apps can&#39;t be cracked anymore, LuckyPatcher&#39;s best years are over anyway.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Classic Power Menu
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/KieronQuinn/ClassicPowerMenu&quot;&gt;https://github.com/KieronQuinn/ClassicPowerMenu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cool but I don&#39;t really use it.&lt;/li&gt;
&lt;li&gt;Takes a bit too long to run the first time after reboot, which is most of the time I open the power menu.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MMRL, WebUI X
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/DerGoogler/MMRL&quot;&gt;https://github.com/DerGoogler/MMRL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mmrl.dev/guide/webuix/&quot;&gt;https://mmrl.dev/guide/webuix/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Only useful with root.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Shizuku (Sui) enabled apps&lt;/h2&gt;
&lt;p&gt;Shizuku grants ADB, whether Sui grants root acces.
In reality, most apps that use Sui can also use Shizuku, usually for the exact same features.&lt;/p&gt;
&lt;h3&gt;Will work with Shizuku&lt;/h3&gt;
&lt;p&gt;(They need it for one-time setup, or something I do once in a while)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lemmy Redirect, Mastodon Redirect, PeerTube Redirect
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/zacharee/MastodonRedirect&quot;&gt;https://github.com/zacharee/MastodonRedirect&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;One-time setup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Install with Options
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/zacharee/InstallWithOptions&quot;&gt;https://github.com/zacharee/InstallWithOptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I use it only once in a while.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Canta
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/samolego/Canta&quot;&gt;https://github.com/samolego/Canta&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Debloating is not needed on GrapheneOS.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;aShell You
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/DP-Hridayan/aShellYou&quot;&gt;https://github.com/DP-Hridayan/aShellYou&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I don&#39;t need to run adb commands often.&lt;/li&gt;
&lt;li&gt;It&#39;s usually used for granting some unusual permission. (WRITE_SECURE_SETTINGS)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SaverTuner
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codeberg.org/s1m/savertuner&quot;&gt;https://codeberg.org/s1m/savertuner&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Needs the WRITE_SECURE_SETTINGS permission.&lt;/li&gt;
&lt;li&gt;One-time setup.&lt;/li&gt;
&lt;li&gt;The Pixel 7 Pro has a pretty good battery life with GrapheneOS, so it&#39;s default power saving mode will probably be enough.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Used Shizuku for installing apps without user confirmation&lt;/h3&gt;
&lt;p&gt;On newer android versions, you only have to confirm once for each app (store), and that gives the store permanent permission to update that app. Thus there&#39;s no need for root for installing.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bunny Manager
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bunny-mod/BunnyManager&quot;&gt;https://github.com/bunny-mod/BunnyManager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Also unmaintained.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Aurora Store
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gitlab.com/AuroraOSS/AuroraStore&quot;&gt;https://gitlab.com/AuroraOSS/AuroraStore&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Droid-ify
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Droid-ify/client&quot;&gt;https://github.com/Droid-ify/client&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Obtainium
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ImranR98/Obtainium&quot;&gt;https://github.com/ImranR98/Obtainium&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Didn&#39;t &lt;strong&gt;actually&lt;/strong&gt; use them&lt;/h3&gt;
&lt;p&gt;These are interesting, because when I first rooted my phone, I was really excited about them. Before that, I&#39;ve always stumbled upon them in some F-Droid repo, and thought how great it would be if I had root and could use them. Well, turns out they aren&#39;t so useful as they seem, and I stopped using most of these apps shortly after I installed them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SystemUI Tuner
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/zacharee/Tweaker&quot;&gt;https://github.com/zacharee/Tweaker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LogFox
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/F0x1d/LogFox&quot;&gt;https://github.com/F0x1d/LogFox&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Geto
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JackEblan/Geto&quot;&gt;https://github.com/JackEblan/Geto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Extinguish
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Moderpach/Extinguish&quot;&gt;https://github.com/Moderpach/Extinguish&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Blocker
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/lihenggui/blocker&quot;&gt;https://github.com/lihenggui/blocker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I was not careful and managed to break QR code payment in my banking app for a few months with the help of this app.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Smartspacer
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/KieronQuinn/Smartspacer&quot;&gt;https://github.com/KieronQuinn/Smartspacer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Will miss&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Hail
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/aistra0528/Hail&quot;&gt;https://github.com/aistra0528/Hail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Freezes apps.&lt;/li&gt;
&lt;li&gt;I use it to freeze proprietary apps that I unfortunately need every so often.
I don&#39;t want them to have any chance to run unless I specifically start them - that&#39;s why I freeze them with Hail.
&lt;ul&gt;
&lt;li&gt;Google Maps&lt;/li&gt;
&lt;li&gt;Google Home (for Chromecast)&lt;/li&gt;
&lt;li&gt;Google (for Lens)&lt;/li&gt;
&lt;li&gt;Spotify (for &lt;a href=&quot;https://support.spotify.com/us/article/jam/&quot;&gt;Jam&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Before you lecture me on how I shouldn&#39;t use these apps at all&lt;/em&gt;:
Especially in the case of Maps and Lens, there are emergency situations where getting somewhere quickly (a hospital, a pharmacy), or identifying some object quickly (unknown pills that your child swallowed) is infinitely more important than privacy. With Hail, it&#39;s like if the apps were uninstalled when they are frozen, but I can still launch them immediately.&lt;/li&gt;
&lt;li&gt;I freeze and unfreeze often, so starting Shizuku every time is not an option.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;alternatives:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Hail could be used with Device Admin / &lt;a href=&quot;https://github.com/iamr0s/Dhizuku&quot;&gt;Dhizuku&lt;/a&gt;, but with some &lt;a href=&quot;https://github.com/GrapheneOS/os-issue-tracker/issues/5710#issuecomment-3250128973&quot;&gt;annoying side effects&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://codeberg.org/raiiware/ForceStopHelper&quot;&gt;Force Stop Helper&lt;/a&gt; is an app list that allows pinning apps to the top, indicates if an app is disabled, and when you click on the app, it takes you to it&#39;s system settings. You can open Force Stop Helper, and disable/enable any app with two clicks.&lt;/li&gt;
&lt;li&gt;Based on GrapheneOS&#39;s response in &lt;a href=&quot;https://discuss.grapheneos.org/d/1173-taskmanager-real-killing-of-processes&quot;&gt;this thread&lt;/a&gt;, I understand that freezing apps might be completely unnecessary, and I can just forbid them running in the background.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;As I&#39;m finishing this blog post, I&#39;ve been using the new Pixel 7 Pro with GrapheneOS for more than two months. I don&#39;t really miss the features I lost with giving up root access, which was very counterintuitive for me, given the amount of them that I used. What&#39;s maybe more surprising is that I miss some non-root features much more - features that I didn&#39;t even know were Samsung-specific. Given enough caffeine, I&#39;ll try to write a blog post about that. Some day...&lt;/p&gt;
&lt;p&gt;Thank you for reading! I don&#39;t have a comment system on my website yet, but &lt;a href=&quot;https://f.cz/@stepan/115605548632900402&quot;&gt;here&#39;s a link to a Mastodon post where you can comment&lt;/a&gt;. Feel free to comment any corrections, recommendations, or just thoughts that crossed your mind while reading this.&lt;/p&gt;
&lt;p&gt;I also &lt;a href=&quot;https://lemmy.cafe/post/27405118?scrollToComments=true&quot;&gt;posted a link on Lemmy&lt;/a&gt;, and there are some very interesting comments and discussion.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Bots I&#39;ve met on the Fediverse</title>
    <link href="https://stepanzak.cc/blog/fediverse-bots/" />
    <updated>2025-02-26T23:00:00Z</updated>
    <id>https://stepanzak.cc/blog/fediverse-bots/</id>
    <content type="html">&lt;p&gt;Wandering around in &lt;a href=&quot;https://jointhefediverse.net/&quot;&gt;the Fediverse&lt;/a&gt;, every once in a while I run into a bot.
It might be weird or ordinary, boring or exciting, interesting or completely absurd.
Here, I want to share those I&#39;m always excited to see again,
and thus think they are worth sharing.&lt;/p&gt;
&lt;h2&gt;I Hope This Email Finds You&lt;/h2&gt;
&lt;p&gt;First bot on this list is also my favorite. I&#39;ll let it introduce itself:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Posts (...) completions to the sentence &amp;quot;I hope this email finds you.&amp;quot;
All content is sourced from Google Books,
based on searches for phrases that start with &amp;quot;finds you.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pretty simple, right?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://stepanzak.cc/blog/fediverse-bots/thisemailfindsyou.jpg&quot; alt=&quot;A screenshot of post by &amp;quot;I Hope This Email Finds You&amp;quot; (@thisemailfindsyou@mastodon.social) with the text &amp;quot;I hope this email finds you unprepared while cross-country skiing.&amp;quot;&quot;&gt;
Every time I&#39;m writing an e-mail, I have the urge to use one of this bot&#39;s creations.&lt;/p&gt;
&lt;p&gt;I find it incredible how amusing a bot posting literal nonsense can be,
especially in an AI age where an LLM can spit out hundreds of sentences like this
in a few seconds.
That wouldn&#39;t be so funny though, would it?&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Click to show Mastodon feed&lt;/summary&gt;
&lt;p&gt;Most recent posts of &lt;a href=&quot;https://mastodon.social/@thisemailfindsyou&quot;&gt;@thisemailfindsyou@mastodon.social&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;mastodon-feed&quot;&gt;
    &lt;style&gt;
      me {
        max-width: 35rem;
        /*center*/
        margin: auto;
        overflow: auto;
      }
    &lt;/style&gt;
  &lt;script&gt;
    window.addEventListener(&quot;load&quot;, () =&gt; {
      const mastoTimeline_UIFrBkr5va = new MastodonTimeline.Init({
      mtContainerId: &quot;mt-container-UIFrBkr5va&quot;,
      instanceUrl: &quot;https://mastodon.social&quot;,
      timelineType: &quot;profile&quot;, 
       userId: &quot;112343635227295007&quot;, 
       profileName: &quot;thisemailfindsyou&quot;, 

      
      
       hideReplies: true, 
       hideUnlisted: true, 
       hideReblog: true, 
      
      
      
      
      
      
      
        });
      })
  &lt;/script&gt;
  &lt;div id=&quot;mt-container-UIFrBkr5va&quot; class=&quot;mt-container&quot;&gt;
    &lt;div class=&quot;mt-body&quot; role=&quot;feed&quot;&gt;
      &lt;div class=&quot;mt-loading-spinner&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/details&gt;
&lt;h2&gt;How to do anything&lt;/h2&gt;
&lt;p&gt;This bot is similar to the previous one in its dadaist nature.
It mixes up random &lt;a href=&quot;https://www.wikihow.com&quot;&gt;wikiHow&lt;/a&gt; article headings and illustrations.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://stepanzak.cc/blog/fediverse-bots/wikihow.jpg&quot; alt=&quot;A screenshot of post by &amp;quot;how to do anything&amp;quot; (@wikihow@mastodon.social) with the text &amp;quot;How to Choose the Right Man to Marry&amp;quot; and an image of a bird feeder. There&#39;s a mark saying that it&#39;s 1.5m (5 ft) above the ground.&quot;&gt;&lt;/p&gt;
&lt;p&gt;Whether you try to find sense it its cryptic advice, or just go for a laugh,
I&#39;m sure it will be glad to see someone listening to what it has to say.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Click to show Mastodon feed&lt;/summary&gt;
&lt;p&gt;Most recent posts of &lt;a href=&quot;https://mastodon.social/@wikihow&quot;&gt;@wikihow@mastodon.social&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;mastodon-feed&quot;&gt;
    &lt;style&gt;
      me {
        max-width: 35rem;
        /*center*/
        margin: auto;
        overflow: auto;
      }
    &lt;/style&gt;
  &lt;script&gt;
    window.addEventListener(&quot;load&quot;, () =&gt; {
      const mastoTimeline_kDCHkojCev = new MastodonTimeline.Init({
      mtContainerId: &quot;mt-container-kDCHkojCev&quot;,
      instanceUrl: &quot;https://mastodon.social&quot;,
      timelineType: &quot;profile&quot;, 
       userId: &quot;417391&quot;, 
       profileName: &quot;wikihow&quot;, 

      
      
       hideReplies: true, 
       hideUnlisted: true, 
       hideReblog: true, 
      
      
      
      
      
      
      
        });
      })
  &lt;/script&gt;
  &lt;div id=&quot;mt-container-kDCHkojCev&quot; class=&quot;mt-container&quot;&gt;
    &lt;div class=&quot;mt-body&quot; role=&quot;feed&quot;&gt;
      &lt;div class=&quot;mt-loading-spinner&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/details&gt;
&lt;h2&gt;As the Film Ends&lt;/h2&gt;
&lt;p&gt;Have you ever opened a random book from your grandma&#39;s bookshelf and read the last page,
or last sentence of it?
There&#39;s something exciting about it, even when you have no idea about the context.
Maybe because of it.&lt;/p&gt;
&lt;p&gt;If you did, you and this bot are gonna love each other!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://stepanzak.cc/blog/fediverse-bots/movieending.jpg&quot; alt=&quot;A screenshot of post by &amp;quot;As the Film Ends&amp;quot; (@endingsummary@mastodon.social) with the text &amp;quot;El Mariachi then gives his share of the cash to his home village before walking into the sunset.&amp;quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Its father &lt;a href=&quot;http://vectorpoem.com/bots/#plotbot&quot;&gt;explains&lt;/a&gt; its inner workings well:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Most Wikipedia pages for a given film provide at least a brief plot synopsis.
Using the sum total of all film pages on Wikipedia as a corpus,
this bot picks a random film and posts the final sentence from its plot summary.
Spoilers are definitely possible, but given the depth of the corpus
it&#39;ll usually be a film you&#39;ve never heard of.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;details&gt;
&lt;summary&gt;Click to show Mastodon feed&lt;/summary&gt;
&lt;p&gt;Most recent posts of &lt;a href=&quot;https://mastodon.social/@endingsummary&quot;&gt;@endingsummary@mastodon.social&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;mastodon-feed&quot;&gt;
    &lt;style&gt;
      me {
        max-width: 35rem;
        /*center*/
        margin: auto;
        overflow: auto;
      }
    &lt;/style&gt;
  &lt;script&gt;
    window.addEventListener(&quot;load&quot;, () =&gt; {
      const mastoTimeline_SfN1m6byGv = new MastodonTimeline.Init({
      mtContainerId: &quot;mt-container-SfN1m6byGv&quot;,
      instanceUrl: &quot;https://mastodon.social&quot;,
      timelineType: &quot;profile&quot;, 
       userId: &quot;403977&quot;, 
       profileName: &quot;endingsummary&quot;, 

      
      
       hideReplies: true, 
       hideUnlisted: true, 
       hideReblog: true, 
      
      
      
      
      
      
      
        });
      })
  &lt;/script&gt;
  &lt;div id=&quot;mt-container-SfN1m6byGv&quot; class=&quot;mt-container&quot;&gt;
    &lt;div class=&quot;mt-body&quot; role=&quot;feed&quot;&gt;
      &lt;div class=&quot;mt-loading-spinner&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/details&gt;
&lt;h2&gt;transect575&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://stepanzak.cc/blog/fediverse-bots/transect575.png&quot; alt=&quot;A screenshot of post by transect575 with a three line haiku
&amp;quot;missing lower half (newline)
may be humpback whale , breaching (newline)
update conditions&amp;quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://bots.converged.yt/@transect575&quot;&gt;transect575&lt;/a&gt; is another bot whose introduction I&#39;ll &lt;a href=&quot;https://converged.yt/bots/#transect575&quot;&gt;leave to its creator&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When I worked for REDACTED GOVERNMENT AGENCY I saw a lot of aerial survey data
from people looking for whales in the sea.
Usually this includes useful information like the number of animals,
whether they are juvenile or adult and weather conditions.
They also usually included a comment field.
So I scraped that out and this bot makes haikus from it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Its home is a &lt;a href=&quot;https://gotosocial.org/&quot;&gt;GoToSocial&lt;/a&gt; instance, so I can&#39;t embed its posts here
as easily as those of bots living on Mastodon.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://bots.converged.yt/@transect575&quot;&gt;Click here&lt;/a&gt; to view transect575&#39;s haikus&lt;/p&gt;
&lt;h2&gt;You Can&#39;t Spell&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://stepanzak.cc/blog/fediverse-bots/youcantspell.jpg&quot; alt=&quot;A screenshot of post by &amp;quot;You Can&#39;t Spell&amp;quot; (@cantspell@mastodon.social) with the text &amp;quot;You can&#39;t spell artificial intelligence without lie certificating&amp;quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;This bot is only six days old when I&#39;m writing this,
but it already managed to say smarter things than
lot of adults I know have ever said.
Did you know that you can&#39;t spell &lt;em&gt;warm-hearted&lt;/em&gt; without &lt;em&gt;meth award&lt;/em&gt;?&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Click to show Mastodon feed&lt;/summary&gt;
&lt;p&gt;Most recent posts of &lt;a href=&quot;https://mastodon.social/@cantspell&quot;&gt;@cantspell@mastodon.social&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;mastodon-feed&quot;&gt;
    &lt;style&gt;
      me {
        max-width: 35rem;
        /*center*/
        margin: auto;
        overflow: auto;
      }
    &lt;/style&gt;
  &lt;script&gt;
    window.addEventListener(&quot;load&quot;, () =&gt; {
      const mastoTimeline_T6GLxJ82uo = new MastodonTimeline.Init({
      mtContainerId: &quot;mt-container-T6GLxJ82uo&quot;,
      instanceUrl: &quot;https://mastodon.social&quot;,
      timelineType: &quot;profile&quot;, 
       userId: &quot;114039513726375451&quot;, 
       profileName: &quot;cantspell&quot;, 

      
      
       hideReplies: true, 
       hideUnlisted: true, 
       hideReblog: true, 
      
      
      
      
      
      
      
        });
      })
  &lt;/script&gt;
  &lt;div id=&quot;mt-container-T6GLxJ82uo&quot; class=&quot;mt-container&quot;&gt;
    &lt;div class=&quot;mt-body&quot; role=&quot;feed&quot;&gt;
      &lt;div class=&quot;mt-loading-spinner&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/details&gt;
&lt;h2&gt;Shakespearean Insult Bot&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://stepanzak.cc/blog/fediverse-bots/shakespeareinsult.jpg&quot; alt=&quot;A screenshot of post by &amp;quot;Shakespearean Insult Bot&amp;quot; (@shakespearean_Insults@beige.party) with the text &amp;quot;You degenerate, fat-kidneyed, onion-eyed, scut!&amp;quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Nothing much to say about the &lt;em&gt;Shakespearean Insult Bot&lt;/em&gt;,
who walks around the Fediverse and insults whoever crosses its path.
Its unloved (those not starred/boosted/commented) insults are deleted after two weeks,
which is a pretty clever feature that the &lt;em&gt;How to do anything&lt;/em&gt; bot could borrow.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Click to show Mastodon feed&lt;/summary&gt;
&lt;p&gt;Most recent posts of &lt;a href=&quot;https://beige.party/@shakespearean_Insults&quot;&gt;@shakespearean_Insults@beige.party&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;mastodon-feed&quot;&gt;
    &lt;style&gt;
      me {
        max-width: 35rem;
        /*center*/
        margin: auto;
        overflow: auto;
      }
    &lt;/style&gt;
  &lt;script&gt;
    window.addEventListener(&quot;load&quot;, () =&gt; {
      const mastoTimeline_lkhskI2JK3 = new MastodonTimeline.Init({
      mtContainerId: &quot;mt-container-lkhskI2JK3&quot;,
      instanceUrl: &quot;https://beige.party&quot;,
      timelineType: &quot;profile&quot;, 
       userId: &quot;113725385831519563&quot;, 
       profileName: &quot;shakespearean_Insults&quot;, 

      
      
       hideReplies: true, 
       hideUnlisted: true, 
       hideReblog: true, 
      
      
      
      
      
      
      
        });
      })
  &lt;/script&gt;
  &lt;div id=&quot;mt-container-lkhskI2JK3&quot; class=&quot;mt-container&quot;&gt;
    &lt;div class=&quot;mt-body&quot; role=&quot;feed&quot;&gt;
      &lt;div class=&quot;mt-loading-spinner&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/details&gt;
&lt;h2&gt;SimCity2000 Traffic Helicopter&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://stepanzak.cc/blog/fediverse-bots/simcity.jpg&quot; alt=&quot;A screenshot of post by &amp;quot;SimCity2000 Traffic Helicopter&amp;quot; (@sc2000@mastodon.social) with an image of a Sim City 2000 city and the text &amp;quot;1.5 MIL! June 24, 3963&amp;quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Last bot on this list is a bit different than the rest.
It&#39;s not funny nor nonsensical, but deserves its place more than any other.&lt;/p&gt;
&lt;p&gt;Another project of &lt;a href=&quot;https://mastodon.social/@jplebreton&quot;&gt;@jplebreton@mastodon.social&lt;/a&gt;,
creator of the &lt;em&gt;As the Film Ends&lt;/em&gt; bot,
&lt;em&gt;SimCity2000 Traffic Helicopter&lt;/em&gt; &lt;a href=&quot;http://vectorpoem.com/bots/#sc2000bot&quot;&gt;flies above user-created cities and posts a random glimpse of a cityscape.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Beautiful!&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Click to show Mastodon feed&lt;/summary&gt;
&lt;p&gt;Most recent posts of &lt;a href=&quot;https://mastodon.social/@sc2000&quot;&gt;@sc2000@mastodon.social&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;mastodon-feed&quot;&gt;
    &lt;style&gt;
      me {
        max-width: 35rem;
        /*center*/
        margin: auto;
        overflow: auto;
      }
    &lt;/style&gt;
  &lt;script&gt;
    window.addEventListener(&quot;load&quot;, () =&gt; {
      const mastoTimeline_QpWNIYfWZM = new MastodonTimeline.Init({
      mtContainerId: &quot;mt-container-QpWNIYfWZM&quot;,
      instanceUrl: &quot;https://mastodon.social&quot;,
      timelineType: &quot;profile&quot;, 
       userId: &quot;113429291225946141&quot;, 
       profileName: &quot;sc2000&quot;, 

      
      
       hideReplies: true, 
       hideUnlisted: true, 
       hideReblog: true, 
      
      
      
      
      
      
      
        });
      })
  &lt;/script&gt;
  &lt;div id=&quot;mt-container-QpWNIYfWZM&quot; class=&quot;mt-container&quot;&gt;
    &lt;div class=&quot;mt-body&quot; role=&quot;feed&quot;&gt;
      &lt;div class=&quot;mt-loading-spinner&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/details&gt;
</content>
  </entry>
</feed>