Ver código fonte

MVI Architecture Post

codeskraps 6 meses atrás
pai
commit
abc08c2f94

+ 146 - 13
content/posts/mvi_architecture.md

@@ -1,10 +1,14 @@
 +++
-title = 'MVI Architecture Helper'
+title = 'Simplifying MVI Architecture in Kotlin: A Powerful Helper Class'
 date = 2024-09-27T13:45:09+02:00
-tags = ['kotlin', 'kmp', 'android', 'mvi']
-draft = true
+tags = ['kotlin', 'kmp', 'android', 'mvi', 'architecture', 'mvvm', 'viewmodel']
+draft = false
 +++
-Something smart to talk about this helper class
+Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we'll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.
+<!--more-->
+## The MVI Helper Class
+
+First, let's look at the complete helper class:
 
 {{< highlight kotlin >}}
 interface StateReceiver<STATE> {
@@ -12,7 +16,9 @@ interface StateReceiver<STATE> {
     suspend fun withState(block: suspend (STATE) -> Unit)
 }
 
-suspend inline fun <reified TYPE : STATE, STATE> StateReceiver<STATE>.withType(crossinline block: suspend (TYPE) -> Unit) {
+suspend inline fun <reified TYPE : STATE, STATE> StateReceiver<STATE>.withType(
+    crossinline block: suspend (TYPE) -> Unit
+) {
     withState { state ->
         if (state is TYPE) {
             block(state)
@@ -20,8 +26,12 @@ suspend inline fun <reified TYPE : STATE, STATE> StateReceiver<STATE>.withType(c
     }
 }
 
-suspend inline fun <reified TYPE : STATE, STATE> StateReceiver<STATE>.updateWithType(crossinline transform: suspend (TYPE) -> TYPE) {
-    withType<TYPE, STATE> { state -> updateState { transform(state) } }
+suspend inline fun <reified TYPE : STATE, STATE> StateReceiver<STATE>.updateWithType(
+    crossinline transform: suspend (TYPE) -> TYPE
+) {
+    withType<TYPE, STATE> { state ->
+        updateState { transform(state) }
+    }
 }
 
 interface StateProvider<STATE> {
@@ -44,15 +54,11 @@ interface StateModule<STATE> : StateReceiver<STATE>, StateProvider<STATE>
 interface IntentModule<INTENT> : IntentReceiver<INTENT>
 interface ActionModule<ACTION> : ActionReceiver<ACTION>, ActionProvider<ACTION>
 
-interface MVIViewModel<STATE, INTENT, ACTION> :
-    StateModule<STATE>,
-    IntentModule<INTENT>,
-    ActionModule<ACTION>
+interface MVIViewModel<STATE, INTENT, ACTION> : StateModule<STATE>, IntentModule<INTENT>, ActionModule<ACTION>
 
 class MVIViewModelDelegate<STATE, INTENT, ACTION>(
     initial: STATE
 ) : MVIViewModel<STATE, INTENT, ACTION> {
-
     private val _state = MutableStateFlow(initial)
     override val state: StateFlow<STATE> = _state.asStateFlow()
 
@@ -75,4 +81,131 @@ class MVIViewModelDelegate<STATE, INTENT, ACTION>(
         throw NotImplementedError()
     }
 }
-{{< / highlight >}}
+{{< /highlight >}}
+
+## Understanding the MVI Helper Class
+
+Let's break down the key components of our MVI helper class:
+
+### Core Interfaces
+
+1. `StateReceiver<STATE>`: Allows updating and accessing the current state.
+2. `StateProvider<STATE>`: Provides access to the state as a `StateFlow`.
+3. `IntentReceiver<INTENT>`: Handles user intents.
+4. `ActionProvider<ACTION>`: Provides a flow of actions.
+5. `ActionReceiver<ACTION>`: Allows sending actions.
+
+### Composite Interfaces
+
+1. `StateModule<STATE>`: Combines state receiving and providing.
+2. `IntentModule<INTENT>`: Wraps intent receiving.
+3. `ActionModule<ACTION>`: Combines action receiving and providing.
+4. `MVIViewModel<STATE, INTENT, ACTION>`: The main interface combining all MVI components.
+
+### Helper Functions
+
+1. `withType`: Allows type-safe state access.
+2. `updateWithType`: Enables type-safe state updates.
+
+### The MVIViewModelDelegate
+
+This class implements the `MVIViewModel` interface, providing a concrete implementation of the MVI pattern.
+
+## Example Implementation
+
+Let's implement a simple counter application using our MVI helper class. Note that we can use either data classes or sealed interfaces for our State, Intent, and Action definitions:
+
+{{< highlight kotlin >}}
+// Define our State, Intent, and Action
+data class CounterState(val count: Int = 0)
+
+sealed interface CounterIntent {
+    object Increment : CounterIntent
+    object Decrement : CounterIntent
+}
+
+sealed interface CounterAction {
+    data class ShowToast(val message: String) : CounterAction
+}
+
+class CounterViewModel : MVIViewModel<CounterState, CounterIntent, CounterAction> by MVIViewModelDelegate(CounterState()) {
+
+    init {
+        handleIntent()
+    }
+
+    private fun handleIntent() = viewModelScope.launch {
+        withState { state ->
+            when (val intent = receiveIntent()) {
+                is CounterIntent.Increment -> updateState { it.copy(count = it.count + 1) }
+                is CounterIntent.Decrement -> updateState { it.copy(count = it.count - 1) }
+            }
+            checkCounterValue(state.count)
+        }
+    }
+
+    private suspend fun checkCounterValue(count: Int) {
+        if (count % 10 == 0 && count != 0) {
+            sendAction { CounterAction.ShowToast("Counter is now $count!") }
+        }
+    }
+}
+{{< /highlight >}}
+
+In this example:
+
+1. We define our `State` as a data class, and our `Intent` and `Action` as sealed interfaces.
+2. The `CounterViewModel` uses the `MVIViewModelDelegate` to implement the `MVIViewModel` interface.
+3. We handle intents in the `handleIntent` function, updating the state based on the received intent.
+4. The `checkCounterValue` function demonstrates how to send actions when certain conditions are met.
+
+## Using the ViewModel in the UI
+
+Here's how you might use this ViewModel in an Android Activity or Fragment:
+
+{{< highlight kotlin >}}
+class CounterActivity : AppCompatActivity() {
+    private val viewModel: CounterViewModel by viewModels()
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_counter)
+
+        // Collect state
+        lifecycleScope.launch {
+            viewModel.state.collect { state ->
+                updateUI(state)
+            }
+        }
+
+        // Collect actions
+        lifecycleScope.launch {
+            viewModel.action.collect { action ->
+                when (action) {
+                    is CounterAction.ShowToast -> Toast.makeText(this@CounterActivity, action.message, Toast.LENGTH_SHORT).show()
+                }
+            }
+        }
+
+        // Send intents
+        incrementButton.setOnClickListener {
+            viewModel.handleIntent(CounterIntent.Increment)
+        }
+        decrementButton.setOnClickListener {
+            viewModel.handleIntent(CounterIntent.Decrement)
+        }
+    }
+
+    private fun updateUI(state: CounterState) {
+        counterTextView.text = state.count.toString()
+    }
+}
+{{< /highlight >}}
+
+## Conclusion
+
+The MVI helper class we've explored simplifies the implementation of the MVI pattern, providing a clean and type-safe way to manage state, handle user intents, and emit actions. By using this helper class, you can create more maintainable and testable view models, leading to more robust applications.
+
+Remember that you can use either data classes or sealed interfaces for your State, Intent, and Action definitions, depending on your specific needs. This flexibility allows you to choose the most appropriate structure for each component of your MVI architecture.
+
+While this helper class provides a solid foundation, you may need to adapt it to fit the specific needs of your project. Happy coding! 

+ 0 - 1
layouts/about/single.html

@@ -5,7 +5,6 @@
           {{ .Title }}
         </h1>
       </header>
-
       {{ .Content }}
     </div>
   </article>

+ 0 - 1
public/about/index.html

@@ -70,7 +70,6 @@
           About Me
         </h1>
       </header>
-
       <p>I&rsquo;m a passionate and highly motivated software engineer with a deep-rooted love for technology that dates back to my first computer, an Amstrad 8256. From those early days of programming as a hobby, I&rsquo;ve turned my passion into a successful career, specializing in mobile development with a focus on Android.</p>
 <h2 id="professional-journey">Professional Journey</h2>
 <p>Currently, I&rsquo;m leading the mobile team at Game Golf, where I oversee all aspects of our mobile app development. My experience spans various domains, including:</p>

+ 8 - 1
public/index.xml

@@ -8,7 +8,7 @@
     <language>en-us</language>
     <managingEditor>me@codeskraps.com (codeskraps)</managingEditor>
     <webMaster>me@codeskraps.com (codeskraps)</webMaster>
-    <lastBuildDate>Mon, 01 Jan 0001 00:00:00 +0000</lastBuildDate>
+    <lastBuildDate>Fri, 27 Sep 2024 13:45:09 +0200</lastBuildDate>
     <atom:link href="https://codeskraps.com/index.xml" rel="self" type="application/rss+xml" />
     <item>
       <title>About Me</title>
@@ -17,6 +17,13 @@
       <guid>https://codeskraps.com/about/</guid>
       <description>&lt;p&gt;I&amp;rsquo;m a passionate and highly motivated software engineer with a deep-rooted love for technology that dates back to my first computer, an Amstrad 8256. From those early days of programming as a hobby, I&amp;rsquo;ve turned my passion into a successful career, specializing in mobile development with a focus on Android.&lt;/p&gt;&#xA;&lt;h2 id=&#34;professional-journey&#34;&gt;Professional Journey&lt;/h2&gt;&#xA;&lt;p&gt;Currently, I&amp;rsquo;m leading the mobile team at Game Golf, where I oversee all aspects of our mobile app development. My experience spans various domains, including:&lt;/p&gt;</description>
     </item>
+    <item>
+      <title>Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</title>
+      <link>https://codeskraps.com/posts/mvi_architecture/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/posts/mvi_architecture/</guid>
+      <description>&lt;p&gt;Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&amp;rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.&lt;/p&gt;</description>
+    </item>
     <item>
       <title>Projects</title>
       <link>https://codeskraps.com/projects/</link>

+ 17 - 0
public/posts/index.html

@@ -76,6 +76,23 @@ Posts | codeskraps
 
     <div>
         
+
+        <a class="postListLink" href="https://codeskraps.com/posts/mvi_architecture/">
+            
+            <div class="postListItem" role="listitem">
+                <div class="postHeader">
+                    <span class="postTitle">Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</span>
+                    
+                    <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
+                </div>
+                <div class="postExcerpt">
+                    <p><p>Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.</p></p>
+                </div>
+            </div>
+        </a>
+
+
+        
     </div>
 </div>
 

+ 8 - 1
public/posts/index.xml

@@ -8,7 +8,14 @@
     <language>en-us</language>
     <managingEditor>me@codeskraps.com (codeskraps)</managingEditor>
     <webMaster>me@codeskraps.com (codeskraps)</webMaster>
-    <lastBuildDate></lastBuildDate>
+    <lastBuildDate>Fri, 27 Sep 2024 13:45:09 +0200</lastBuildDate>
     <atom:link href="https://codeskraps.com/posts/index.xml" rel="self" type="application/rss+xml" />
+    <item>
+      <title>Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</title>
+      <link>https://codeskraps.com/posts/mvi_architecture/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/posts/mvi_architecture/</guid>
+      <description>&lt;p&gt;Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&amp;rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.&lt;/p&gt;</description>
+    </item>
   </channel>
 </rss>

+ 135 - 20
public/posts/mvi_architecture/index.html

@@ -1,9 +1,9 @@
 <!DOCTYPE html>
 <html lang="en-us">
 
-<head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=53155&amp;path=livereload" data-no-instant defer></script>
+<head>
     <title>
-MVI Architecture Helper | codeskraps
+Simplifying MVI Architecture in Kotlin: A Powerful Helper Class | codeskraps
 </title>
 
     <meta http-equiv="content-type" content="text/html; charset=utf-8">
@@ -13,7 +13,7 @@ MVI Architecture Helper | codeskraps
 <meta name="generator" content="Hugo 0.134.3">
 
 
-<link rel="canonical" href="http://localhost:53155/posts/mvi_architecture/" >
+<link rel="canonical" href="https://codeskraps.com/posts/mvi_architecture/" >
 
 
 
@@ -31,7 +31,7 @@ MVI Architecture Helper | codeskraps
         <header class="headerWrapper">
     <div class="header">
         <div>
-            <a class="terminal" href="http://localhost:53155/">
+            <a class="terminal" href="https://codeskraps.com/">
                 <span>me@codeskraps.com ~ $</span>
             </a>
         </div>
@@ -41,17 +41,17 @@ MVI Architecture Helper | codeskraps
             <ul>
                 
                 <li>
-                    <a href="http://localhost:53155/projects/" title="" >
+                    <a href="https://codeskraps.com/projects/" title="" >
                         ~/projects</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/about/" title="" >
+                    <a href="https://codeskraps.com/about/" title="" >
                         ~/about</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/posts/" title="" >
+                    <a href="https://codeskraps.com/posts/" title="" >
                         ~/posts</a>
                 </li>
                 
@@ -65,7 +65,7 @@ MVI Architecture Helper | codeskraps
             <main class="main">
                 
 <div class="postWrapper">
-    <h1>MVI Architecture Helper</h1>
+    <h1>Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</h1>
     
     
     <section class="postMetadata">
@@ -77,7 +77,10 @@ MVI Architecture Helper | codeskraps
     <a href="/tags/kotlin/">#Kotlin</a><span></span>
     <a href="/tags/kmp/">#Kmp</a><span></span>
     <a href="/tags/android/">#Android</a><span></span>
-    <a href="/tags/mvi/">#Mvi</a></dd>
+    <a href="/tags/mvi/">#Mvi</a><span></span>
+    <a href="/tags/architecture/">#Architecture</a><span></span>
+    <a href="/tags/mvvm/">#Mvvm</a><span></span>
+    <a href="/tags/viewmodel/">#Viewmodel</a></dd>
             
             
             
@@ -88,19 +91,23 @@ MVI Architecture Helper | codeskraps
             
             
                 <dt>reading time</dt>
-                <dd>1 minute</dd>
+                <dd>4 minutes</dd>
             
         </dl>
     </section>
     
     <div>
-        <p>Something smart to talk about this helper class</p>
+        <p>Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.</p>
+<h2 id="the-mvi-helper-class">The MVI Helper Class</h2>
+<p>First, let&rsquo;s look at the complete helper class:</p>
 <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt; {
 </span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">updateState</span>(transform: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> STATE)
 </span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">withState</span>(block: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> Unit)
 </span></span><span style="display:flex;"><span>}
 </span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.withType(<span style="color:#66d9ef">crossinline</span> block: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> Unit) {
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.withType(
+</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">crossinline</span> block: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> Unit
+</span></span><span style="display:flex;"><span>) {
 </span></span><span style="display:flex;"><span>    withState { state <span style="color:#f92672">-&gt;</span>
 </span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (state <span style="color:#66d9ef">is</span> TYPE) {
 </span></span><span style="display:flex;"><span>            block(state)
@@ -108,8 +115,12 @@ MVI Architecture Helper | codeskraps
 </span></span><span style="display:flex;"><span>    }
 </span></span><span style="display:flex;"><span>}
 </span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.updateWithType(<span style="color:#66d9ef">crossinline</span> transform: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> TYPE) {
-</span></span><span style="display:flex;"><span>    withType&lt;TYPE, STATE&gt; { state <span style="color:#f92672">-&gt;</span> updateState { transform(state) } }
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.updateWithType(
+</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">crossinline</span> transform: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> TYPE
+</span></span><span style="display:flex;"><span>) {
+</span></span><span style="display:flex;"><span>    withType&lt;TYPE, STATE&gt; { state <span style="color:#f92672">-&gt;</span>
+</span></span><span style="display:flex;"><span>        updateState { transform(state) }
+</span></span><span style="display:flex;"><span>    }
 </span></span><span style="display:flex;"><span>}
 </span></span><span style="display:flex;"><span>
 </span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateProvider</span>&lt;STATE&gt; {
@@ -132,15 +143,11 @@ MVI Architecture Helper | codeskraps
 </span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">IntentModule</span>&lt;INTENT&gt; : IntentReceiver&lt;INTENT&gt;
 </span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionModule</span>&lt;ACTION&gt; : ActionReceiver&lt;ACTION&gt;, ActionProvider&lt;ACTION&gt;
 </span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">MVIViewModel</span>&lt;STATE, INTENT, ACTION&gt; :
-</span></span><span style="display:flex;"><span>    StateModule&lt;STATE&gt;,
-</span></span><span style="display:flex;"><span>    IntentModule&lt;INTENT&gt;,
-</span></span><span style="display:flex;"><span>    ActionModule&lt;ACTION&gt;
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">MVIViewModel</span>&lt;STATE, INTENT, ACTION&gt; : StateModule&lt;STATE&gt;, IntentModule&lt;INTENT&gt;, ActionModule&lt;ACTION&gt;
 </span></span><span style="display:flex;"><span>
 </span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MVIViewModelDelegate</span>&lt;STATE, INTENT, ACTION&gt;(
 </span></span><span style="display:flex;"><span>    initial: STATE
 </span></span><span style="display:flex;"><span>) : MVIViewModel&lt;STATE, INTENT, ACTION&gt; {
-</span></span><span style="display:flex;"><span>
 </span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">val</span> _state = MutableStateFlow(initial)
 </span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">val</span> state: StateFlow&lt;STATE&gt; = _state.asStateFlow()
 </span></span><span style="display:flex;"><span>
@@ -163,7 +170,115 @@ MVI Architecture Helper | codeskraps
 </span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">throw</span> NotImplementedError()
 </span></span><span style="display:flex;"><span>    }
 </span></span><span style="display:flex;"><span>}</span></span></code></pre></div>
-
+<h2 id="understanding-the-mvi-helper-class">Understanding the MVI Helper Class</h2>
+<p>Let&rsquo;s break down the key components of our MVI helper class:</p>
+<h3 id="core-interfaces">Core Interfaces</h3>
+<ol>
+<li><code>StateReceiver&lt;STATE&gt;</code>: Allows updating and accessing the current state.</li>
+<li><code>StateProvider&lt;STATE&gt;</code>: Provides access to the state as a <code>StateFlow</code>.</li>
+<li><code>IntentReceiver&lt;INTENT&gt;</code>: Handles user intents.</li>
+<li><code>ActionProvider&lt;ACTION&gt;</code>: Provides a flow of actions.</li>
+<li><code>ActionReceiver&lt;ACTION&gt;</code>: Allows sending actions.</li>
+</ol>
+<h3 id="composite-interfaces">Composite Interfaces</h3>
+<ol>
+<li><code>StateModule&lt;STATE&gt;</code>: Combines state receiving and providing.</li>
+<li><code>IntentModule&lt;INTENT&gt;</code>: Wraps intent receiving.</li>
+<li><code>ActionModule&lt;ACTION&gt;</code>: Combines action receiving and providing.</li>
+<li><code>MVIViewModel&lt;STATE, INTENT, ACTION&gt;</code>: The main interface combining all MVI components.</li>
+</ol>
+<h3 id="helper-functions">Helper Functions</h3>
+<ol>
+<li><code>withType</code>: Allows type-safe state access.</li>
+<li><code>updateWithType</code>: Enables type-safe state updates.</li>
+</ol>
+<h3 id="the-mviviewmodeldelegate">The MVIViewModelDelegate</h3>
+<p>This class implements the <code>MVIViewModel</code> interface, providing a concrete implementation of the MVI pattern.</p>
+<h2 id="example-implementation">Example Implementation</h2>
+<p>Let&rsquo;s implement a simple counter application using our MVI helper class. Note that we can use either data classes or sealed interfaces for our State, Intent, and Action definitions:</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span><span style="color:#75715e">// Define our State, Intent, and Action
+</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">data</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">CounterState</span>(<span style="color:#66d9ef">val</span> count: Int = <span style="color:#ae81ff">0</span>)
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">sealed</span> <span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">CounterIntent</span> {
+</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">object</span> <span style="color:#a6e22e">Increment</span> : CounterIntent
+</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">object</span> <span style="color:#a6e22e">Decrement</span> : CounterIntent
+</span></span><span style="display:flex;"><span>}
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">sealed</span> <span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">CounterAction</span> {
+</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">data</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ShowToast</span>(<span style="color:#66d9ef">val</span> message: String) : CounterAction
+</span></span><span style="display:flex;"><span>}
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">CounterViewModel</span> : MVIViewModel&lt;CounterState, CounterIntent, CounterAction&gt; <span style="color:#66d9ef">by</span> MVIViewModelDelegate(CounterState()) {
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">init</span> {
+</span></span><span style="display:flex;"><span>        handleIntent()
+</span></span><span style="display:flex;"><span>    }
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">handleIntent</span>() = viewModelScope.launch {
+</span></span><span style="display:flex;"><span>        withState { state <span style="color:#f92672">-&gt;</span>
+</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">when</span> (<span style="color:#66d9ef">val</span> intent = receiveIntent()) {
+</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">is</span> <span style="color:#a6e22e">CounterIntent</span>.Increment <span style="color:#f92672">-&gt;</span> updateState { <span style="color:#66d9ef">it</span>.copy(count = <span style="color:#66d9ef">it</span>.count + <span style="color:#ae81ff">1</span>) }
+</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">is</span> <span style="color:#a6e22e">CounterIntent</span>.Decrement <span style="color:#f92672">-&gt;</span> updateState { <span style="color:#66d9ef">it</span>.copy(count = <span style="color:#66d9ef">it</span>.count - <span style="color:#ae81ff">1</span>) }
+</span></span><span style="display:flex;"><span>            }
+</span></span><span style="display:flex;"><span>            checkCounterValue(state.count)
+</span></span><span style="display:flex;"><span>        }
+</span></span><span style="display:flex;"><span>    }
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">checkCounterValue</span>(count: Int) {
+</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (count % <span style="color:#ae81ff">10</span> <span style="color:#f92672">==</span> <span style="color:#ae81ff">0</span> <span style="color:#f92672">&amp;&amp;</span> count <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span>) {
+</span></span><span style="display:flex;"><span>            sendAction { <span style="color:#a6e22e">CounterAction</span>.ShowToast(<span style="color:#e6db74">&#34;Counter is now </span><span style="color:#e6db74">$count</span><span style="color:#e6db74">!&#34;</span>) }
+</span></span><span style="display:flex;"><span>        }
+</span></span><span style="display:flex;"><span>    }
+</span></span><span style="display:flex;"><span>}</span></span></code></pre></div>
+<p>In this example:</p>
+<ol>
+<li>We define our <code>State</code> as a data class, and our <code>Intent</code> and <code>Action</code> as sealed interfaces.</li>
+<li>The <code>CounterViewModel</code> uses the <code>MVIViewModelDelegate</code> to implement the <code>MVIViewModel</code> interface.</li>
+<li>We handle intents in the <code>handleIntent</code> function, updating the state based on the received intent.</li>
+<li>The <code>checkCounterValue</code> function demonstrates how to send actions when certain conditions are met.</li>
+</ol>
+<h2 id="using-the-viewmodel-in-the-ui">Using the ViewModel in the UI</h2>
+<p>Here&rsquo;s how you might use this ViewModel in an Android Activity or Fragment:</p>
+<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">CounterActivity</span> : AppCompatActivity() {
+</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">val</span> viewModel: CounterViewModel <span style="color:#66d9ef">by</span> viewModels()
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">onCreate</span>(savedInstanceState: Bundle?) {
+</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">super</span>.onCreate(savedInstanceState)
+</span></span><span style="display:flex;"><span>        setContentView(<span style="color:#a6e22e">R</span>.layout.activity_counter)
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Collect state
+</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        lifecycleScope.launch {
+</span></span><span style="display:flex;"><span>            viewModel.state.collect { state <span style="color:#f92672">-&gt;</span>
+</span></span><span style="display:flex;"><span>                updateUI(state)
+</span></span><span style="display:flex;"><span>            }
+</span></span><span style="display:flex;"><span>        }
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Collect actions
+</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        lifecycleScope.launch {
+</span></span><span style="display:flex;"><span>            viewModel.action.collect { action <span style="color:#f92672">-&gt;</span>
+</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">when</span> (action) {
+</span></span><span style="display:flex;"><span>                    <span style="color:#66d9ef">is</span> <span style="color:#a6e22e">CounterAction</span>.ShowToast <span style="color:#f92672">-&gt;</span> <span style="color:#a6e22e">Toast</span>.makeText(<span style="color:#66d9ef">this</span><span style="color:#a6e22e">@CounterActivity</span>, action.message, <span style="color:#a6e22e">Toast</span>.LENGTH_SHORT).show()
+</span></span><span style="display:flex;"><span>                }
+</span></span><span style="display:flex;"><span>            }
+</span></span><span style="display:flex;"><span>        }
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Send intents
+</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        incrementButton.setOnClickListener {
+</span></span><span style="display:flex;"><span>            viewModel.handleIntent(<span style="color:#a6e22e">CounterIntent</span>.Increment)
+</span></span><span style="display:flex;"><span>        }
+</span></span><span style="display:flex;"><span>        decrementButton.setOnClickListener {
+</span></span><span style="display:flex;"><span>            viewModel.handleIntent(<span style="color:#a6e22e">CounterIntent</span>.Decrement)
+</span></span><span style="display:flex;"><span>        }
+</span></span><span style="display:flex;"><span>    }
+</span></span><span style="display:flex;"><span>
+</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">updateUI</span>(state: CounterState) {
+</span></span><span style="display:flex;"><span>        counterTextView.text = state.count.toString()
+</span></span><span style="display:flex;"><span>    }
+</span></span><span style="display:flex;"><span>}</span></span></code></pre></div>
+<h2 id="conclusion">Conclusion</h2>
+<p>The MVI helper class we&rsquo;ve explored simplifies the implementation of the MVI pattern, providing a clean and type-safe way to manage state, handle user intents, and emit actions. By using this helper class, you can create more maintainable and testable view models, leading to more robust applications.</p>
+<p>Remember that you can use either data classes or sealed interfaces for your State, Intent, and Action definitions, depending on your specific needs. This flexibility allows you to choose the most appropriate structure for each component of your MVI architecture.</p>
+<p>While this helper class provides a solid foundation, you may need to adapt it to fit the specific needs of your project. Happy coding!</p>
     </div>
 </div>
 

+ 6 - 6
public/posts/my-first-post/index.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en-us">
 
-<head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=53155&amp;path=livereload" data-no-instant defer></script>
+<head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=62956&amp;path=livereload" data-no-instant defer></script>
     <title>
 My First Post | codeskraps
 </title>
@@ -13,7 +13,7 @@ My First Post | codeskraps
 <meta name="generator" content="Hugo 0.134.3">
 
 
-<link rel="canonical" href="http://localhost:53155/posts/my-first-post/" >
+<link rel="canonical" href="http://localhost:62956/posts/my-first-post/" >
 
 
 
@@ -31,7 +31,7 @@ My First Post | codeskraps
         <header class="headerWrapper">
     <div class="header">
         <div>
-            <a class="terminal" href="http://localhost:53155/">
+            <a class="terminal" href="http://localhost:62956/">
                 <span>me@codeskraps.com ~ $</span>
             </a>
         </div>
@@ -41,17 +41,17 @@ My First Post | codeskraps
             <ul>
                 
                 <li>
-                    <a href="http://localhost:53155/projects/" title="" >
+                    <a href="http://localhost:62956/projects/" title="" >
                         ~/projects</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/about/" title="" >
+                    <a href="http://localhost:62956/about/" title="" >
                         ~/about</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/posts/" title="" >
+                    <a href="http://localhost:62956/posts/" title="" >
                         ~/posts</a>
                 </li>
                 

+ 0 - 1
public/projects/index.html

@@ -70,7 +70,6 @@
           Projects
         </h1>
       </header>
-
       <p>
 
 

+ 27 - 2
public/sitemap.xml

@@ -3,17 +3,42 @@
   xmlns:xhtml="http://www.w3.org/1999/xhtml">
   <url>
     <loc>https://codeskraps.com/about/</loc>
+  </url><url>
+    <loc>https://codeskraps.com/tags/android/</loc>
+    <lastmod>2024-09-27T13:45:09+02:00</lastmod>
+  </url><url>
+    <loc>https://codeskraps.com/tags/architecture/</loc>
+    <lastmod>2024-09-27T13:45:09+02:00</lastmod>
   </url><url>
     <loc>https://codeskraps.com/</loc>
     <lastmod>2024-09-27T13:45:09+02:00</lastmod>
+  </url><url>
+    <loc>https://codeskraps.com/tags/kmp/</loc>
+    <lastmod>2024-09-27T13:45:09+02:00</lastmod>
+  </url><url>
+    <loc>https://codeskraps.com/tags/kotlin/</loc>
+    <lastmod>2024-09-27T13:45:09+02:00</lastmod>
+  </url><url>
+    <loc>https://codeskraps.com/tags/mvi/</loc>
+    <lastmod>2024-09-27T13:45:09+02:00</lastmod>
+  </url><url>
+    <loc>https://codeskraps.com/tags/mvvm/</loc>
+    <lastmod>2024-09-27T13:45:09+02:00</lastmod>
   </url><url>
     <loc>https://codeskraps.com/posts/</loc>
     <lastmod>2024-09-27T13:45:09+02:00</lastmod>
+  </url><url>
+    <loc>https://codeskraps.com/posts/mvi_architecture/</loc>
+    <lastmod>2024-09-27T13:45:09+02:00</lastmod>
+  </url><url>
+    <loc>https://codeskraps.com/tags/</loc>
+    <lastmod>2024-09-27T13:45:09+02:00</lastmod>
+  </url><url>
+    <loc>https://codeskraps.com/tags/viewmodel/</loc>
+    <lastmod>2024-09-27T13:45:09+02:00</lastmod>
   </url><url>
     <loc>https://codeskraps.com/categories/</loc>
   </url><url>
     <loc>https://codeskraps.com/projects/</loc>
-  </url><url>
-    <loc>https://codeskraps.com/tags/</loc>
   </url>
 </urlset>

+ 11 - 79
public/tags/android/index.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en-us">
 
-<head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=53155&amp;path=livereload" data-no-instant defer></script>
+<head>
     <title>
 Android | codeskraps
 </title>
@@ -13,9 +13,9 @@ Android | codeskraps
 <meta name="generator" content="Hugo 0.134.3">
 
 
-<link rel="canonical" href="http://localhost:53155/tags/android/" >
-  <link href="http://localhost:53155/tags/android/index.xml" rel="alternate" type="application/rss+xml" title="codeskraps" >
-  <link href="http://localhost:53155/tags/android/index.xml" rel="feed" type="application/rss+xml" title="codeskraps" >
+<link rel="canonical" href="https://codeskraps.com/tags/android/" >
+  <link href="https://codeskraps.com/tags/android/index.xml" rel="alternate" type="application/rss+xml" title="codeskraps" >
+  <link href="https://codeskraps.com/tags/android/index.xml" rel="feed" type="application/rss+xml" title="codeskraps" >
 
 
 
@@ -33,7 +33,7 @@ Android | codeskraps
         <header class="headerWrapper">
     <div class="header">
         <div>
-            <a class="terminal" href="http://localhost:53155/">
+            <a class="terminal" href="https://codeskraps.com/">
                 <span>me@codeskraps.com ~ $</span>
             </a>
         </div>
@@ -43,17 +43,17 @@ Android | codeskraps
             <ul>
                 
                 <li>
-                    <a href="http://localhost:53155/projects/" title="" >
+                    <a href="https://codeskraps.com/projects/" title="" >
                         ~/projects</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/about/" title="" >
+                    <a href="https://codeskraps.com/about/" title="" >
                         ~/about</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/posts/" title="" >
+                    <a href="https://codeskraps.com/posts/" title="" >
                         ~/posts</a>
                 </li>
                 
@@ -77,84 +77,16 @@ Android | codeskraps
     <div>
         
 
-        <a class="postListLink" href="http://localhost:53155/posts/mvi_architecture/">
+        <a class="postListLink" href="https://codeskraps.com/posts/mvi_architecture/">
             
             <div class="postListItem" role="listitem">
                 <div class="postHeader">
-                    <span class="postTitle">MVI Architecture Helper</span>
+                    <span class="postTitle">Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</span>
                     
                     <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
                 </div>
                 <div class="postExcerpt">
-                    <p><p>Something smart to talk about this helper class</p>
-<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">updateState</span>(transform: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> STATE)
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">withState</span>(block: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> Unit)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.withType(<span style="color:#66d9ef">crossinline</span> block: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> Unit) {
-</span></span><span style="display:flex;"><span>    withState { state <span style="color:#f92672">-&gt;</span>
-</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (state <span style="color:#66d9ef">is</span> TYPE) {
-</span></span><span style="display:flex;"><span>            block(state)
-</span></span><span style="display:flex;"><span>        }
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.updateWithType(<span style="color:#66d9ef">crossinline</span> transform: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> TYPE) {
-</span></span><span style="display:flex;"><span>    withType&lt;TYPE, STATE&gt; { state <span style="color:#f92672">-&gt;</span> updateState { transform(state) } }
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateProvider</span>&lt;STATE&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">val</span> state: StateFlow&lt;STATE&gt;
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">IntentReceiver</span>&lt;INTENT&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">handleIntent</span>(intent: INTENT)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionProvider</span>&lt;ACTION&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">val</span> action: Flow&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionReceiver</span>&lt;ACTION&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">sendAction</span>(block: <span style="color:#66d9ef">suspend</span> () <span style="color:#f92672">-&gt;</span> ACTION)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateModule</span>&lt;STATE&gt; : StateReceiver&lt;STATE&gt;, StateProvider&lt;STATE&gt;
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">IntentModule</span>&lt;INTENT&gt; : IntentReceiver&lt;INTENT&gt;
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionModule</span>&lt;ACTION&gt; : ActionReceiver&lt;ACTION&gt;, ActionProvider&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">MVIViewModel</span>&lt;STATE, INTENT, ACTION&gt; :
-</span></span><span style="display:flex;"><span>    StateModule&lt;STATE&gt;,
-</span></span><span style="display:flex;"><span>    IntentModule&lt;INTENT&gt;,
-</span></span><span style="display:flex;"><span>    ActionModule&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MVIViewModelDelegate</span>&lt;STATE, INTENT, ACTION&gt;(
-</span></span><span style="display:flex;"><span>    initial: STATE
-</span></span><span style="display:flex;"><span>) : MVIViewModel&lt;STATE, INTENT, ACTION&gt; {
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">val</span> _state = MutableStateFlow(initial)
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">val</span> state: StateFlow&lt;STATE&gt; = _state.asStateFlow()
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">val</span> _action = Channel&lt;ACTION&gt;()
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">val</span> action: Flow&lt;ACTION&gt; = _action.receiveAsFlow()
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">updateState</span>(transform: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> STATE) {
-</span></span><span style="display:flex;"><span>        _state.update { transform(<span style="color:#66d9ef">it</span>) }
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">withState</span>(block: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> Unit) {
-</span></span><span style="display:flex;"><span>        block(_state.<span style="color:#66d9ef">value</span>)
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">sendAction</span>(block: <span style="color:#66d9ef">suspend</span> () <span style="color:#f92672">-&gt;</span> ACTION) {
-</span></span><span style="display:flex;"><span>        _action.trySend(block())
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">handleIntent</span>(intent: INTENT) {
-</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">throw</span> NotImplementedError()
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></p>
+                    <p><p>Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.</p></p>
                 </div>
             </div>
         </a>

Diferenças do arquivo suprimidas por serem muito extensas
+ 4 - 5
public/tags/android/index.xml


+ 113 - 0
public/tags/architecture/index.html

@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html lang="en-us">
+
+<head>
+    <title>
+Architecture | codeskraps
+</title>
+
+    <meta http-equiv="content-type" content="text/html; charset=utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<meta name="description" content="Your website description">
+
+<meta name="generator" content="Hugo 0.134.3">
+
+
+<link rel="canonical" href="https://codeskraps.com/tags/architecture/" >
+  <link href="https://codeskraps.com/tags/architecture/index.xml" rel="alternate" type="application/rss+xml" title="codeskraps" >
+  <link href="https://codeskraps.com/tags/architecture/index.xml" rel="feed" type="application/rss+xml" title="codeskraps" >
+
+
+
+
+<link href="/css/style.min.ee0d47e4d4346c71a65a9e873108c81ffae54d60a2fc2338f6df394eb4b25a82.css" rel="stylesheet">
+
+
+
+
+</head>
+
+<body>
+
+    <div class="flexWrapper">
+        <header class="headerWrapper">
+    <div class="header">
+        <div>
+            <a class="terminal" href="https://codeskraps.com/">
+                <span>me@codeskraps.com ~ $</span>
+            </a>
+        </div>
+        <input class="side-menu" type="checkbox" id="side-menu">
+        <label class="hamb" for="side-menu"><span class="hamb-line"></span></label>
+        <nav class="headerLinks">
+            <ul>
+                
+                <li>
+                    <a href="https://codeskraps.com/projects/" title="" >
+                        ~/projects</a>
+                </li>
+                
+                <li>
+                    <a href="https://codeskraps.com/about/" title="" >
+                        ~/about</a>
+                </li>
+                
+                <li>
+                    <a href="https://codeskraps.com/posts/" title="" >
+                        ~/posts</a>
+                </li>
+                
+            </ul>
+        </nav>
+    </div>
+</header>
+
+
+        <div class="content">
+            <main class="main">
+                
+
+<div>
+    <div class="listHeader">
+        <h1>Architecture</h1>
+    </div>
+
+    
+
+    <div>
+        
+
+        <a class="postListLink" href="https://codeskraps.com/posts/mvi_architecture/">
+            
+            <div class="postListItem" role="listitem">
+                <div class="postHeader">
+                    <span class="postTitle">Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</span>
+                    
+                    <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
+                </div>
+                <div class="postExcerpt">
+                    <p><p>Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.</p></p>
+                </div>
+            </div>
+        </a>
+
+
+        
+    </div>
+</div>
+
+
+            </main>
+        </div>
+
+
+        <footer class="footer">
+    
+        <span>CC-0, Built with <a href="https://gohugo.io" class="footerLink">Hugo</a> and <a href="https://github.com/LordMathis/hugo-theme-nightfall" class="footerLink">Nightfall</a> theme</span>
+    
+</footer>
+    </div>
+
+</body>
+
+</html>

+ 21 - 0
public/tags/architecture/index.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+  <channel>
+    <title>Architecture on codeskraps</title>
+    <link>https://codeskraps.com/tags/architecture/</link>
+    <description>Recent content in Architecture on codeskraps</description>
+    <generator>Hugo</generator>
+    <language>en-us</language>
+    <managingEditor>me@codeskraps.com (codeskraps)</managingEditor>
+    <webMaster>me@codeskraps.com (codeskraps)</webMaster>
+    <lastBuildDate>Fri, 27 Sep 2024 13:45:09 +0200</lastBuildDate>
+    <atom:link href="https://codeskraps.com/tags/architecture/index.xml" rel="self" type="application/rss+xml" />
+    <item>
+      <title>Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</title>
+      <link>https://codeskraps.com/posts/mvi_architecture/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/posts/mvi_architecture/</guid>
+      <description>&lt;p&gt;Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&amp;rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.&lt;/p&gt;</description>
+    </item>
+  </channel>
+</rss>

+ 119 - 0
public/tags/index.html

@@ -76,6 +76,125 @@ Tags | codeskraps
 
     <div>
         
+
+        <a class="postListLink" href="https://codeskraps.com/tags/android/">
+            
+            <div class="postListItem" role="listitem">
+                <div class="postHeader">
+                    <span class="postTitle">Android</span>
+                    
+                    <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
+                </div>
+                <div class="postExcerpt">
+                    <p></p>
+                </div>
+            </div>
+        </a>
+
+
+        
+
+        <a class="postListLink" href="https://codeskraps.com/tags/architecture/">
+            
+            <div class="postListItem" role="listitem">
+                <div class="postHeader">
+                    <span class="postTitle">Architecture</span>
+                    
+                    <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
+                </div>
+                <div class="postExcerpt">
+                    <p></p>
+                </div>
+            </div>
+        </a>
+
+
+        
+
+        <a class="postListLink" href="https://codeskraps.com/tags/kmp/">
+            
+            <div class="postListItem" role="listitem">
+                <div class="postHeader">
+                    <span class="postTitle">Kmp</span>
+                    
+                    <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
+                </div>
+                <div class="postExcerpt">
+                    <p></p>
+                </div>
+            </div>
+        </a>
+
+
+        
+
+        <a class="postListLink" href="https://codeskraps.com/tags/kotlin/">
+            
+            <div class="postListItem" role="listitem">
+                <div class="postHeader">
+                    <span class="postTitle">Kotlin</span>
+                    
+                    <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
+                </div>
+                <div class="postExcerpt">
+                    <p></p>
+                </div>
+            </div>
+        </a>
+
+
+        
+
+        <a class="postListLink" href="https://codeskraps.com/tags/mvi/">
+            
+            <div class="postListItem" role="listitem">
+                <div class="postHeader">
+                    <span class="postTitle">Mvi</span>
+                    
+                    <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
+                </div>
+                <div class="postExcerpt">
+                    <p></p>
+                </div>
+            </div>
+        </a>
+
+
+        
+
+        <a class="postListLink" href="https://codeskraps.com/tags/mvvm/">
+            
+            <div class="postListItem" role="listitem">
+                <div class="postHeader">
+                    <span class="postTitle">Mvvm</span>
+                    
+                    <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
+                </div>
+                <div class="postExcerpt">
+                    <p></p>
+                </div>
+            </div>
+        </a>
+
+
+        
+
+        <a class="postListLink" href="https://codeskraps.com/tags/viewmodel/">
+            
+            <div class="postListItem" role="listitem">
+                <div class="postHeader">
+                    <span class="postTitle">Viewmodel</span>
+                    
+                    <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
+                </div>
+                <div class="postExcerpt">
+                    <p></p>
+                </div>
+            </div>
+        </a>
+
+
+        
     </div>
 </div>
 

+ 50 - 0
public/tags/index.xml

@@ -8,6 +8,56 @@
     <language>en-us</language>
     <managingEditor>me@codeskraps.com (codeskraps)</managingEditor>
     <webMaster>me@codeskraps.com (codeskraps)</webMaster>
+    <lastBuildDate>Fri, 27 Sep 2024 13:45:09 +0200</lastBuildDate>
     <atom:link href="https://codeskraps.com/tags/index.xml" rel="self" type="application/rss+xml" />
+    <item>
+      <title>Android</title>
+      <link>https://codeskraps.com/tags/android/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/tags/android/</guid>
+      <description></description>
+    </item>
+    <item>
+      <title>Architecture</title>
+      <link>https://codeskraps.com/tags/architecture/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/tags/architecture/</guid>
+      <description></description>
+    </item>
+    <item>
+      <title>Kmp</title>
+      <link>https://codeskraps.com/tags/kmp/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/tags/kmp/</guid>
+      <description></description>
+    </item>
+    <item>
+      <title>Kotlin</title>
+      <link>https://codeskraps.com/tags/kotlin/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/tags/kotlin/</guid>
+      <description></description>
+    </item>
+    <item>
+      <title>Mvi</title>
+      <link>https://codeskraps.com/tags/mvi/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/tags/mvi/</guid>
+      <description></description>
+    </item>
+    <item>
+      <title>Mvvm</title>
+      <link>https://codeskraps.com/tags/mvvm/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/tags/mvvm/</guid>
+      <description></description>
+    </item>
+    <item>
+      <title>Viewmodel</title>
+      <link>https://codeskraps.com/tags/viewmodel/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/tags/viewmodel/</guid>
+      <description></description>
+    </item>
   </channel>
 </rss>

+ 11 - 79
public/tags/kmp/index.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en-us">
 
-<head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=53155&amp;path=livereload" data-no-instant defer></script>
+<head>
     <title>
 Kmp | codeskraps
 </title>
@@ -13,9 +13,9 @@ Kmp | codeskraps
 <meta name="generator" content="Hugo 0.134.3">
 
 
-<link rel="canonical" href="http://localhost:53155/tags/kmp/" >
-  <link href="http://localhost:53155/tags/kmp/index.xml" rel="alternate" type="application/rss+xml" title="codeskraps" >
-  <link href="http://localhost:53155/tags/kmp/index.xml" rel="feed" type="application/rss+xml" title="codeskraps" >
+<link rel="canonical" href="https://codeskraps.com/tags/kmp/" >
+  <link href="https://codeskraps.com/tags/kmp/index.xml" rel="alternate" type="application/rss+xml" title="codeskraps" >
+  <link href="https://codeskraps.com/tags/kmp/index.xml" rel="feed" type="application/rss+xml" title="codeskraps" >
 
 
 
@@ -33,7 +33,7 @@ Kmp | codeskraps
         <header class="headerWrapper">
     <div class="header">
         <div>
-            <a class="terminal" href="http://localhost:53155/">
+            <a class="terminal" href="https://codeskraps.com/">
                 <span>me@codeskraps.com ~ $</span>
             </a>
         </div>
@@ -43,17 +43,17 @@ Kmp | codeskraps
             <ul>
                 
                 <li>
-                    <a href="http://localhost:53155/projects/" title="" >
+                    <a href="https://codeskraps.com/projects/" title="" >
                         ~/projects</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/about/" title="" >
+                    <a href="https://codeskraps.com/about/" title="" >
                         ~/about</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/posts/" title="" >
+                    <a href="https://codeskraps.com/posts/" title="" >
                         ~/posts</a>
                 </li>
                 
@@ -77,84 +77,16 @@ Kmp | codeskraps
     <div>
         
 
-        <a class="postListLink" href="http://localhost:53155/posts/mvi_architecture/">
+        <a class="postListLink" href="https://codeskraps.com/posts/mvi_architecture/">
             
             <div class="postListItem" role="listitem">
                 <div class="postHeader">
-                    <span class="postTitle">MVI Architecture Helper</span>
+                    <span class="postTitle">Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</span>
                     
                     <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
                 </div>
                 <div class="postExcerpt">
-                    <p><p>Something smart to talk about this helper class</p>
-<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">updateState</span>(transform: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> STATE)
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">withState</span>(block: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> Unit)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.withType(<span style="color:#66d9ef">crossinline</span> block: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> Unit) {
-</span></span><span style="display:flex;"><span>    withState { state <span style="color:#f92672">-&gt;</span>
-</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (state <span style="color:#66d9ef">is</span> TYPE) {
-</span></span><span style="display:flex;"><span>            block(state)
-</span></span><span style="display:flex;"><span>        }
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.updateWithType(<span style="color:#66d9ef">crossinline</span> transform: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> TYPE) {
-</span></span><span style="display:flex;"><span>    withType&lt;TYPE, STATE&gt; { state <span style="color:#f92672">-&gt;</span> updateState { transform(state) } }
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateProvider</span>&lt;STATE&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">val</span> state: StateFlow&lt;STATE&gt;
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">IntentReceiver</span>&lt;INTENT&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">handleIntent</span>(intent: INTENT)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionProvider</span>&lt;ACTION&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">val</span> action: Flow&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionReceiver</span>&lt;ACTION&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">sendAction</span>(block: <span style="color:#66d9ef">suspend</span> () <span style="color:#f92672">-&gt;</span> ACTION)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateModule</span>&lt;STATE&gt; : StateReceiver&lt;STATE&gt;, StateProvider&lt;STATE&gt;
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">IntentModule</span>&lt;INTENT&gt; : IntentReceiver&lt;INTENT&gt;
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionModule</span>&lt;ACTION&gt; : ActionReceiver&lt;ACTION&gt;, ActionProvider&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">MVIViewModel</span>&lt;STATE, INTENT, ACTION&gt; :
-</span></span><span style="display:flex;"><span>    StateModule&lt;STATE&gt;,
-</span></span><span style="display:flex;"><span>    IntentModule&lt;INTENT&gt;,
-</span></span><span style="display:flex;"><span>    ActionModule&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MVIViewModelDelegate</span>&lt;STATE, INTENT, ACTION&gt;(
-</span></span><span style="display:flex;"><span>    initial: STATE
-</span></span><span style="display:flex;"><span>) : MVIViewModel&lt;STATE, INTENT, ACTION&gt; {
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">val</span> _state = MutableStateFlow(initial)
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">val</span> state: StateFlow&lt;STATE&gt; = _state.asStateFlow()
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">val</span> _action = Channel&lt;ACTION&gt;()
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">val</span> action: Flow&lt;ACTION&gt; = _action.receiveAsFlow()
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">updateState</span>(transform: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> STATE) {
-</span></span><span style="display:flex;"><span>        _state.update { transform(<span style="color:#66d9ef">it</span>) }
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">withState</span>(block: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> Unit) {
-</span></span><span style="display:flex;"><span>        block(_state.<span style="color:#66d9ef">value</span>)
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">sendAction</span>(block: <span style="color:#66d9ef">suspend</span> () <span style="color:#f92672">-&gt;</span> ACTION) {
-</span></span><span style="display:flex;"><span>        _action.trySend(block())
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">handleIntent</span>(intent: INTENT) {
-</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">throw</span> NotImplementedError()
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></p>
+                    <p><p>Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.</p></p>
                 </div>
             </div>
         </a>

Diferenças do arquivo suprimidas por serem muito extensas
+ 4 - 5
public/tags/kmp/index.xml


+ 11 - 79
public/tags/kotlin/index.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en-us">
 
-<head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=53155&amp;path=livereload" data-no-instant defer></script>
+<head>
     <title>
 Kotlin | codeskraps
 </title>
@@ -13,9 +13,9 @@ Kotlin | codeskraps
 <meta name="generator" content="Hugo 0.134.3">
 
 
-<link rel="canonical" href="http://localhost:53155/tags/kotlin/" >
-  <link href="http://localhost:53155/tags/kotlin/index.xml" rel="alternate" type="application/rss+xml" title="codeskraps" >
-  <link href="http://localhost:53155/tags/kotlin/index.xml" rel="feed" type="application/rss+xml" title="codeskraps" >
+<link rel="canonical" href="https://codeskraps.com/tags/kotlin/" >
+  <link href="https://codeskraps.com/tags/kotlin/index.xml" rel="alternate" type="application/rss+xml" title="codeskraps" >
+  <link href="https://codeskraps.com/tags/kotlin/index.xml" rel="feed" type="application/rss+xml" title="codeskraps" >
 
 
 
@@ -33,7 +33,7 @@ Kotlin | codeskraps
         <header class="headerWrapper">
     <div class="header">
         <div>
-            <a class="terminal" href="http://localhost:53155/">
+            <a class="terminal" href="https://codeskraps.com/">
                 <span>me@codeskraps.com ~ $</span>
             </a>
         </div>
@@ -43,17 +43,17 @@ Kotlin | codeskraps
             <ul>
                 
                 <li>
-                    <a href="http://localhost:53155/projects/" title="" >
+                    <a href="https://codeskraps.com/projects/" title="" >
                         ~/projects</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/about/" title="" >
+                    <a href="https://codeskraps.com/about/" title="" >
                         ~/about</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/posts/" title="" >
+                    <a href="https://codeskraps.com/posts/" title="" >
                         ~/posts</a>
                 </li>
                 
@@ -77,84 +77,16 @@ Kotlin | codeskraps
     <div>
         
 
-        <a class="postListLink" href="http://localhost:53155/posts/mvi_architecture/">
+        <a class="postListLink" href="https://codeskraps.com/posts/mvi_architecture/">
             
             <div class="postListItem" role="listitem">
                 <div class="postHeader">
-                    <span class="postTitle">MVI Architecture Helper</span>
+                    <span class="postTitle">Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</span>
                     
                     <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
                 </div>
                 <div class="postExcerpt">
-                    <p><p>Something smart to talk about this helper class</p>
-<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">updateState</span>(transform: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> STATE)
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">withState</span>(block: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> Unit)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.withType(<span style="color:#66d9ef">crossinline</span> block: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> Unit) {
-</span></span><span style="display:flex;"><span>    withState { state <span style="color:#f92672">-&gt;</span>
-</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (state <span style="color:#66d9ef">is</span> TYPE) {
-</span></span><span style="display:flex;"><span>            block(state)
-</span></span><span style="display:flex;"><span>        }
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.updateWithType(<span style="color:#66d9ef">crossinline</span> transform: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> TYPE) {
-</span></span><span style="display:flex;"><span>    withType&lt;TYPE, STATE&gt; { state <span style="color:#f92672">-&gt;</span> updateState { transform(state) } }
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateProvider</span>&lt;STATE&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">val</span> state: StateFlow&lt;STATE&gt;
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">IntentReceiver</span>&lt;INTENT&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">handleIntent</span>(intent: INTENT)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionProvider</span>&lt;ACTION&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">val</span> action: Flow&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionReceiver</span>&lt;ACTION&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">sendAction</span>(block: <span style="color:#66d9ef">suspend</span> () <span style="color:#f92672">-&gt;</span> ACTION)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateModule</span>&lt;STATE&gt; : StateReceiver&lt;STATE&gt;, StateProvider&lt;STATE&gt;
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">IntentModule</span>&lt;INTENT&gt; : IntentReceiver&lt;INTENT&gt;
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionModule</span>&lt;ACTION&gt; : ActionReceiver&lt;ACTION&gt;, ActionProvider&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">MVIViewModel</span>&lt;STATE, INTENT, ACTION&gt; :
-</span></span><span style="display:flex;"><span>    StateModule&lt;STATE&gt;,
-</span></span><span style="display:flex;"><span>    IntentModule&lt;INTENT&gt;,
-</span></span><span style="display:flex;"><span>    ActionModule&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MVIViewModelDelegate</span>&lt;STATE, INTENT, ACTION&gt;(
-</span></span><span style="display:flex;"><span>    initial: STATE
-</span></span><span style="display:flex;"><span>) : MVIViewModel&lt;STATE, INTENT, ACTION&gt; {
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">val</span> _state = MutableStateFlow(initial)
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">val</span> state: StateFlow&lt;STATE&gt; = _state.asStateFlow()
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">val</span> _action = Channel&lt;ACTION&gt;()
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">val</span> action: Flow&lt;ACTION&gt; = _action.receiveAsFlow()
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">updateState</span>(transform: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> STATE) {
-</span></span><span style="display:flex;"><span>        _state.update { transform(<span style="color:#66d9ef">it</span>) }
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">withState</span>(block: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> Unit) {
-</span></span><span style="display:flex;"><span>        block(_state.<span style="color:#66d9ef">value</span>)
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">sendAction</span>(block: <span style="color:#66d9ef">suspend</span> () <span style="color:#f92672">-&gt;</span> ACTION) {
-</span></span><span style="display:flex;"><span>        _action.trySend(block())
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">handleIntent</span>(intent: INTENT) {
-</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">throw</span> NotImplementedError()
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></p>
+                    <p><p>Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.</p></p>
                 </div>
             </div>
         </a>

Diferenças do arquivo suprimidas por serem muito extensas
+ 4 - 5
public/tags/kotlin/index.xml


+ 11 - 79
public/tags/mvi/index.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en-us">
 
-<head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=53155&amp;path=livereload" data-no-instant defer></script>
+<head>
     <title>
 Mvi | codeskraps
 </title>
@@ -13,9 +13,9 @@ Mvi | codeskraps
 <meta name="generator" content="Hugo 0.134.3">
 
 
-<link rel="canonical" href="http://localhost:53155/tags/mvi/" >
-  <link href="http://localhost:53155/tags/mvi/index.xml" rel="alternate" type="application/rss+xml" title="codeskraps" >
-  <link href="http://localhost:53155/tags/mvi/index.xml" rel="feed" type="application/rss+xml" title="codeskraps" >
+<link rel="canonical" href="https://codeskraps.com/tags/mvi/" >
+  <link href="https://codeskraps.com/tags/mvi/index.xml" rel="alternate" type="application/rss+xml" title="codeskraps" >
+  <link href="https://codeskraps.com/tags/mvi/index.xml" rel="feed" type="application/rss+xml" title="codeskraps" >
 
 
 
@@ -33,7 +33,7 @@ Mvi | codeskraps
         <header class="headerWrapper">
     <div class="header">
         <div>
-            <a class="terminal" href="http://localhost:53155/">
+            <a class="terminal" href="https://codeskraps.com/">
                 <span>me@codeskraps.com ~ $</span>
             </a>
         </div>
@@ -43,17 +43,17 @@ Mvi | codeskraps
             <ul>
                 
                 <li>
-                    <a href="http://localhost:53155/projects/" title="" >
+                    <a href="https://codeskraps.com/projects/" title="" >
                         ~/projects</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/about/" title="" >
+                    <a href="https://codeskraps.com/about/" title="" >
                         ~/about</a>
                 </li>
                 
                 <li>
-                    <a href="http://localhost:53155/posts/" title="" >
+                    <a href="https://codeskraps.com/posts/" title="" >
                         ~/posts</a>
                 </li>
                 
@@ -77,84 +77,16 @@ Mvi | codeskraps
     <div>
         
 
-        <a class="postListLink" href="http://localhost:53155/posts/mvi_architecture/">
+        <a class="postListLink" href="https://codeskraps.com/posts/mvi_architecture/">
             
             <div class="postListItem" role="listitem">
                 <div class="postHeader">
-                    <span class="postTitle">MVI Architecture Helper</span>
+                    <span class="postTitle">Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</span>
                     
                     <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
                 </div>
                 <div class="postExcerpt">
-                    <p><p>Something smart to talk about this helper class</p>
-<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-kotlin" data-lang="kotlin"><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">updateState</span>(transform: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> STATE)
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">withState</span>(block: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> Unit)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.withType(<span style="color:#66d9ef">crossinline</span> block: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> Unit) {
-</span></span><span style="display:flex;"><span>    withState { state <span style="color:#f92672">-&gt;</span>
-</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (state <span style="color:#66d9ef">is</span> TYPE) {
-</span></span><span style="display:flex;"><span>            block(state)
-</span></span><span style="display:flex;"><span>        }
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">fun</span> &lt;<span style="color:#66d9ef">reified</span> <span style="color:#a6e22e">TYPE</span> : <span style="color:#a6e22e">STATE</span>, <span style="color:#a6e22e">STATE</span>&gt; <span style="color:#a6e22e">StateReceiver</span>&lt;STATE&gt;.updateWithType(<span style="color:#66d9ef">crossinline</span> transform: <span style="color:#66d9ef">suspend</span> (TYPE) <span style="color:#f92672">-&gt;</span> TYPE) {
-</span></span><span style="display:flex;"><span>    withType&lt;TYPE, STATE&gt; { state <span style="color:#f92672">-&gt;</span> updateState { transform(state) } }
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateProvider</span>&lt;STATE&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">val</span> state: StateFlow&lt;STATE&gt;
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">IntentReceiver</span>&lt;INTENT&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">handleIntent</span>(intent: INTENT)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionProvider</span>&lt;ACTION&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">val</span> action: Flow&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionReceiver</span>&lt;ACTION&gt; {
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">sendAction</span>(block: <span style="color:#66d9ef">suspend</span> () <span style="color:#f92672">-&gt;</span> ACTION)
-</span></span><span style="display:flex;"><span>}
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">StateModule</span>&lt;STATE&gt; : StateReceiver&lt;STATE&gt;, StateProvider&lt;STATE&gt;
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">IntentModule</span>&lt;INTENT&gt; : IntentReceiver&lt;INTENT&gt;
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">ActionModule</span>&lt;ACTION&gt; : ActionReceiver&lt;ACTION&gt;, ActionProvider&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">MVIViewModel</span>&lt;STATE, INTENT, ACTION&gt; :
-</span></span><span style="display:flex;"><span>    StateModule&lt;STATE&gt;,
-</span></span><span style="display:flex;"><span>    IntentModule&lt;INTENT&gt;,
-</span></span><span style="display:flex;"><span>    ActionModule&lt;ACTION&gt;
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MVIViewModelDelegate</span>&lt;STATE, INTENT, ACTION&gt;(
-</span></span><span style="display:flex;"><span>    initial: STATE
-</span></span><span style="display:flex;"><span>) : MVIViewModel&lt;STATE, INTENT, ACTION&gt; {
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">val</span> _state = MutableStateFlow(initial)
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">val</span> state: StateFlow&lt;STATE&gt; = _state.asStateFlow()
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">val</span> _action = Channel&lt;ACTION&gt;()
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">val</span> action: Flow&lt;ACTION&gt; = _action.receiveAsFlow()
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">updateState</span>(transform: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> STATE) {
-</span></span><span style="display:flex;"><span>        _state.update { transform(<span style="color:#66d9ef">it</span>) }
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">withState</span>(block: <span style="color:#66d9ef">suspend</span> (STATE) <span style="color:#f92672">-&gt;</span> Unit) {
-</span></span><span style="display:flex;"><span>        block(_state.<span style="color:#66d9ef">value</span>)
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">suspend</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">sendAction</span>(block: <span style="color:#66d9ef">suspend</span> () <span style="color:#f92672">-&gt;</span> ACTION) {
-</span></span><span style="display:flex;"><span>        _action.trySend(block())
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>
-</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">override</span> <span style="color:#66d9ef">fun</span> <span style="color:#a6e22e">handleIntent</span>(intent: INTENT) {
-</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">throw</span> NotImplementedError()
-</span></span><span style="display:flex;"><span>    }
-</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></p>
+                    <p><p>Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.</p></p>
                 </div>
             </div>
         </a>

Diferenças do arquivo suprimidas por serem muito extensas
+ 4 - 5
public/tags/mvi/index.xml


+ 113 - 0
public/tags/mvvm/index.html

@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html lang="en-us">
+
+<head>
+    <title>
+Mvvm | codeskraps
+</title>
+
+    <meta http-equiv="content-type" content="text/html; charset=utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<meta name="description" content="Your website description">
+
+<meta name="generator" content="Hugo 0.134.3">
+
+
+<link rel="canonical" href="https://codeskraps.com/tags/mvvm/" >
+  <link href="https://codeskraps.com/tags/mvvm/index.xml" rel="alternate" type="application/rss+xml" title="codeskraps" >
+  <link href="https://codeskraps.com/tags/mvvm/index.xml" rel="feed" type="application/rss+xml" title="codeskraps" >
+
+
+
+
+<link href="/css/style.min.ee0d47e4d4346c71a65a9e873108c81ffae54d60a2fc2338f6df394eb4b25a82.css" rel="stylesheet">
+
+
+
+
+</head>
+
+<body>
+
+    <div class="flexWrapper">
+        <header class="headerWrapper">
+    <div class="header">
+        <div>
+            <a class="terminal" href="https://codeskraps.com/">
+                <span>me@codeskraps.com ~ $</span>
+            </a>
+        </div>
+        <input class="side-menu" type="checkbox" id="side-menu">
+        <label class="hamb" for="side-menu"><span class="hamb-line"></span></label>
+        <nav class="headerLinks">
+            <ul>
+                
+                <li>
+                    <a href="https://codeskraps.com/projects/" title="" >
+                        ~/projects</a>
+                </li>
+                
+                <li>
+                    <a href="https://codeskraps.com/about/" title="" >
+                        ~/about</a>
+                </li>
+                
+                <li>
+                    <a href="https://codeskraps.com/posts/" title="" >
+                        ~/posts</a>
+                </li>
+                
+            </ul>
+        </nav>
+    </div>
+</header>
+
+
+        <div class="content">
+            <main class="main">
+                
+
+<div>
+    <div class="listHeader">
+        <h1>Mvvm</h1>
+    </div>
+
+    
+
+    <div>
+        
+
+        <a class="postListLink" href="https://codeskraps.com/posts/mvi_architecture/">
+            
+            <div class="postListItem" role="listitem">
+                <div class="postHeader">
+                    <span class="postTitle">Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</span>
+                    
+                    <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
+                </div>
+                <div class="postExcerpt">
+                    <p><p>Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.</p></p>
+                </div>
+            </div>
+        </a>
+
+
+        
+    </div>
+</div>
+
+
+            </main>
+        </div>
+
+
+        <footer class="footer">
+    
+        <span>CC-0, Built with <a href="https://gohugo.io" class="footerLink">Hugo</a> and <a href="https://github.com/LordMathis/hugo-theme-nightfall" class="footerLink">Nightfall</a> theme</span>
+    
+</footer>
+    </div>
+
+</body>
+
+</html>

+ 21 - 0
public/tags/mvvm/index.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+  <channel>
+    <title>Mvvm on codeskraps</title>
+    <link>https://codeskraps.com/tags/mvvm/</link>
+    <description>Recent content in Mvvm on codeskraps</description>
+    <generator>Hugo</generator>
+    <language>en-us</language>
+    <managingEditor>me@codeskraps.com (codeskraps)</managingEditor>
+    <webMaster>me@codeskraps.com (codeskraps)</webMaster>
+    <lastBuildDate>Fri, 27 Sep 2024 13:45:09 +0200</lastBuildDate>
+    <atom:link href="https://codeskraps.com/tags/mvvm/index.xml" rel="self" type="application/rss+xml" />
+    <item>
+      <title>Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</title>
+      <link>https://codeskraps.com/posts/mvi_architecture/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/posts/mvi_architecture/</guid>
+      <description>&lt;p&gt;Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&amp;rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.&lt;/p&gt;</description>
+    </item>
+  </channel>
+</rss>

+ 113 - 0
public/tags/viewmodel/index.html

@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html lang="en-us">
+
+<head>
+    <title>
+Viewmodel | codeskraps
+</title>
+
+    <meta http-equiv="content-type" content="text/html; charset=utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<meta name="description" content="Your website description">
+
+<meta name="generator" content="Hugo 0.134.3">
+
+
+<link rel="canonical" href="https://codeskraps.com/tags/viewmodel/" >
+  <link href="https://codeskraps.com/tags/viewmodel/index.xml" rel="alternate" type="application/rss+xml" title="codeskraps" >
+  <link href="https://codeskraps.com/tags/viewmodel/index.xml" rel="feed" type="application/rss+xml" title="codeskraps" >
+
+
+
+
+<link href="/css/style.min.ee0d47e4d4346c71a65a9e873108c81ffae54d60a2fc2338f6df394eb4b25a82.css" rel="stylesheet">
+
+
+
+
+</head>
+
+<body>
+
+    <div class="flexWrapper">
+        <header class="headerWrapper">
+    <div class="header">
+        <div>
+            <a class="terminal" href="https://codeskraps.com/">
+                <span>me@codeskraps.com ~ $</span>
+            </a>
+        </div>
+        <input class="side-menu" type="checkbox" id="side-menu">
+        <label class="hamb" for="side-menu"><span class="hamb-line"></span></label>
+        <nav class="headerLinks">
+            <ul>
+                
+                <li>
+                    <a href="https://codeskraps.com/projects/" title="" >
+                        ~/projects</a>
+                </li>
+                
+                <li>
+                    <a href="https://codeskraps.com/about/" title="" >
+                        ~/about</a>
+                </li>
+                
+                <li>
+                    <a href="https://codeskraps.com/posts/" title="" >
+                        ~/posts</a>
+                </li>
+                
+            </ul>
+        </nav>
+    </div>
+</header>
+
+
+        <div class="content">
+            <main class="main">
+                
+
+<div>
+    <div class="listHeader">
+        <h1>Viewmodel</h1>
+    </div>
+
+    
+
+    <div>
+        
+
+        <a class="postListLink" href="https://codeskraps.com/posts/mvi_architecture/">
+            
+            <div class="postListItem" role="listitem">
+                <div class="postHeader">
+                    <span class="postTitle">Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</span>
+                    
+                    <time class="postDate" datetime="2024-09-27">September 27, 2024</time>
+                </div>
+                <div class="postExcerpt">
+                    <p><p>Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.</p></p>
+                </div>
+            </div>
+        </a>
+
+
+        
+    </div>
+</div>
+
+
+            </main>
+        </div>
+
+
+        <footer class="footer">
+    
+        <span>CC-0, Built with <a href="https://gohugo.io" class="footerLink">Hugo</a> and <a href="https://github.com/LordMathis/hugo-theme-nightfall" class="footerLink">Nightfall</a> theme</span>
+    
+</footer>
+    </div>
+
+</body>
+
+</html>

+ 21 - 0
public/tags/viewmodel/index.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+  <channel>
+    <title>Viewmodel on codeskraps</title>
+    <link>https://codeskraps.com/tags/viewmodel/</link>
+    <description>Recent content in Viewmodel on codeskraps</description>
+    <generator>Hugo</generator>
+    <language>en-us</language>
+    <managingEditor>me@codeskraps.com (codeskraps)</managingEditor>
+    <webMaster>me@codeskraps.com (codeskraps)</webMaster>
+    <lastBuildDate>Fri, 27 Sep 2024 13:45:09 +0200</lastBuildDate>
+    <atom:link href="https://codeskraps.com/tags/viewmodel/index.xml" rel="self" type="application/rss+xml" />
+    <item>
+      <title>Simplifying MVI Architecture in Kotlin: A Powerful Helper Class</title>
+      <link>https://codeskraps.com/posts/mvi_architecture/</link>
+      <pubDate>Fri, 27 Sep 2024 13:45:09 +0200</pubDate><author>me@codeskraps.com (codeskraps)</author>
+      <guid>https://codeskraps.com/posts/mvi_architecture/</guid>
+      <description>&lt;p&gt;Model-View-Intent (MVI) is a powerful architectural pattern for building user interfaces, especially in Android development. In this post, we&amp;rsquo;ll explore a helper class that simplifies the implementation of MVI, making it easier to manage state, handle user intents, and emit actions in your application.&lt;/p&gt;</description>
+    </item>
+  </channel>
+</rss>

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff