From eef534617ced5bed0228ff51de1067693752ee56 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 17 Aug 2023 15:15:13 -0400 Subject: [PATCH] Fixing ThreadAssembler with two roots --- .../amethyst/ThreadAssemblerTest.kt | 146 ++++++++++++++++++ .../com/vitorpamplona/amethyst/model/Note.kt | 13 +- .../amethyst/ui/dal/ThreadFeedFilter.kt | 3 +- 3 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 app/src/androidTest/java/com/vitorpamplona/amethyst/ThreadAssemblerTest.kt diff --git a/app/src/androidTest/java/com/vitorpamplona/amethyst/ThreadAssemblerTest.kt b/app/src/androidTest/java/com/vitorpamplona/amethyst/ThreadAssemblerTest.kt new file mode 100644 index 000000000..1bbf7caeb --- /dev/null +++ b/app/src/androidTest/java/com/vitorpamplona/amethyst/ThreadAssemblerTest.kt @@ -0,0 +1,146 @@ +package com.vitorpamplona.amethyst + +import com.fasterxml.jackson.module.kotlin.readValue +import com.vitorpamplona.amethyst.model.LocalCache +import com.vitorpamplona.amethyst.ui.dal.ThreadFeedFilter +import com.vitorpamplona.quartz.encoders.ATag +import com.vitorpamplona.quartz.events.Event +import junit.framework.TestCase +import junit.framework.TestCase.assertEquals +import org.junit.Test + +class ThreadAssemblerTest { + val db = """ + [ + {"id":"741f5367a9415f4d6f19c0f57a1e4647c8ed8309b53b0da2d82fc4ebfba03b2c","pubkey":"d85c99afd244911e0aaf800cbea4221df557f06f8a4ff2cbe84b24e0b9e728fc","created_at":1684674845,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Getting my head around this","sig":"069874040bac26a219777fc0f90b8f4df71e38c30e3e6a953d53222499d8e0c5a8f32c6b4204d14eb335bb654f01c5610372d9dc00062284b8e0f2bb98c7ed85"}, + {"id":"22323fc72b4c37f93ea21f6069684339ce5f63111161c81f2aa3de4a21bfe83b","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1683571810,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"test","sig":"f6d3bcf0f8e07d06720a2527f95910ee5a66aa889dd9261514921a155bbc3e9a3c7d721f5a2ec948cd795183f85dbe80f2ee2e36663f9d1de33fc03274ccb9d9"}, + {"id":"14525fcaae530a029f782fd361dd0cd66634c3e23020bd19e66fe11c1e254e32","pubkey":"afd563434a737334d69db899e4a32fe38d73a182bb6d1e91d83a2c4c4e04737c","created_at":1682968749,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"This is most amazing thing yet for nostr!","sig":"3dcbb058b8fa6e6f388f5b1a26d21b888dbc91bb831b0ed80ee30d9d2494fbbbb40dac9daf637b948c3afe1f32c2c662eca8d7acc0ba31f23b89edc8ade99631"}, + {"id":"98ae0d6d10e494ed0bf70feb577e8225c6a6732c7af3d29f88bfe1b87d4439e6","pubkey":"83fd07de9b763334cc9d46f2785c2558e6c2eabfe7d0c6ec214667cbaec50d47","created_at":1681995243,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"true if big","sig":"bb7d97e81207096d8615ebb0458c3023fa1b8f3aac463f3f0293ae94e2b90d043ad371067ce984a2ab2ba49cd7432a553f128b8d2d678238551538ad657bd75c"}, + {"id":"36e262e71b7e8bcae946f69885b8c3614e318e82864437342cf50e8b9ab7229d","pubkey":"b111d517452f9ef015e16d60ae623a6b66af63024eec941b0653bfee0dd667d4","created_at":1681979196,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"this is wonderful. great work.","sig":"205a46d867c22cbb09c7dcc4351330a95304c0d80540c85b9ea39f7f464ea60df1ef5006c1f93b862536f04d8a7855e4cc2a915d7a01437cd30f7f12c716b239"}, + {"id":"37725c2924ca267d66c2c27c2dae65550c07e7b883034cf1ea69671883430642","pubkey":"90b9bec74789688e515125596ab6350bfe646176ac75742275063922c5fea010","created_at":1681944950,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Epic!","sig":"c461b97a3cdc5cf967e6f32c59c94b1b912c296feb1cbb7943c81731e558b10a3674982d6990567260d9fb033f5a3d3db8984b1eb362715d68ba46034a8b1b86"}, + {"id":"8ba54cfb6375270e8ae97a7e0992c1a0dbaa4cd46af8309d67a839e86789fde6","pubkey":"c48e29f04b482cc01ca1f9ef8c86ef8318c059e0e9353235162f080f26e14c11","created_at":1681944377,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"This is incredible... Bravo, Pablo, and shoutout to Gigi.","sig":"fb1a84d4859742b001b810c98a5e9301bc861fa2d65a711cb21c57f6e62c98f27e5b0c0c6432ef1111bc6cc52aa8cb0ae909d28af50c497d125950bfaeade475"}, + {"id":"53410bc6d47e87f3f18ecbc93c716b5a6ef8ee3805516b2ff4d155154a685b7c","pubkey":"fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52","created_at":1681945005,"kind":1,"tags":[["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["e","8ba54cfb6375270e8ae97a7e0992c1a0dbaa4cd46af8309d67a839e86789fde6"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["p","c48e29f04b482cc01ca1f9ef8c86ef8318c059e0e9353235162f080f26e14c11"]],"content":"Thank you, my friend 🤙 ","sig":"3d2fbcefdfac2183601076c8f9e518e05620cefe74cba233684cce931a69b51befa329c94734e434805bd9382ff3dad36e42d1955d4e47c822e973ba69b7377f"}, + {"id":"e383476cb1ce5accde11d4b1338424fa32c3724cf96e6214af8e5e852981728a","pubkey":"50de492cfe5472450df1a0176fdf6d915e97cb5d9f8d3eccef7d25ff0a8871de","created_at":1681932060,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"https://nostr.build/p/nb5753.png","sig":"9df6e3872f420ed5225aaa242f1c806b4739f17e265f02ca593a3c31c5fb5cb48705ee6bc0510f81f123527aa96ec4d07adf829362e2196bd7b833deded4c2b8"}, + {"id":"e2d8aaed336d3c0f73a9ca46a89fdb2da62a6d172936a91b0067a68797b3bcb8","pubkey":"50de492cfe5472450df1a0176fdf6d915e97cb5d9f8d3eccef7d25ff0a8871de","created_at":1681931869,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Very Cool, I started playing around!","sig":"5980b2d0ef114d50c5f45b5d0c55bfc56b16a0a1807774ec2a86c4e352e17e3ec78877c73f2fedfbfd097a018df8e965107d6efd4ad9c0a0e1ecc89332d51cec"}, + {"id":"b92e4d6a5d0e8d1d2d2421044b84a4d11f2188261c55145d782b1b6bf0995009","pubkey":"fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52","created_at":1681932193,"kind":1,"tags":[["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f","","root"],["e","e2d8aaed336d3c0f73a9ca46a89fdb2da62a6d172936a91b0067a68797b3bcb8","","reply"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"]],"content":"love seeing it!!!","sig":"47850c205f1fa6d8836cda347c7d12c4307d35a110629eac48b4fff26600a14a5c5c8a7877b851db062a89e0157be112eae60ba0594525c1cc4d355906368dbb"}, + {"id":"da13e14cc8bcc243e0373dde14533d3829b8b621e214ca3c99c90f3dd9e11b8a","pubkey":"b488b594d84bb3e7c8421a4b91b19a006dc13d0c00da304a0263355d02195f04","created_at":1681931637,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Great thoughts ","sig":"34c81430952508746fd5d5a4c4f7df0f5762aeb17d075a74f7b0daf387a7b8772edf4152731cff6650219e1aa9f8f63924410baa03091a698af0513cbf57e0af"}, + {"id":"b5234d90a1543ba60765c57ac3fc7140129a4ac28bbd013531ec9b85e256ea55","pubkey":"b488b594d84bb3e7c8421a4b91b19a006dc13d0c00da304a0263355d02195f04","created_at":1681931560,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"I like comments ","sig":"6915f4c2a08622339957495931eabc37f8d0c50ab1f3ec42327b67d15e50f50ff4bc302848b606e6d7c170696f8d744e6f896223f30ecb39a3adffe58020ff6f"}, + {"id":"fc4e4a1230b002e4ae08251a0b26107de7f518800188b7a504f5de62d8b07996","pubkey":"fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52","created_at":1681834615,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","532808e4d60f5f82b95aeaa3ed2e930a0c5973dccb0ede68b28b1931db91440f"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"This is exactly why I built this. I am enamored by this idea.","sig":"bdd1b3532efa3badeb3807fe74d31c25f17c84bbe39fe3c692d3d73efa39408089843ebb3c049840f2d525e6849f8254179a888bedc776ee7ad5e6997dc10c44"}, + {"id":"d4a0b4f08d98d82a04292654ec132723cc2cf3fa24ffb6c0833426cb9372f4d5","pubkey":"39a8b17475be0db44e313f9fd032ffde183c8abd6498e4932a873330d2cd4868","created_at":1680618462,"kind":1,"tags":[["e","44d3ecbb5752e96becc330d9b56352ea595d37b4c55edd8701fd24f18df5eee2"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["p","39a8b17475be0db44e313f9fd032ffde183c8abd6498e4932a873330d2cd4868"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Unfortunately when boosting this it gets broken 🥹\n#[1]","sig":"c4a4197df4fec008f2f565170d09c46f0b9a7217ed90432cb53d1dddf70ad8520722b6e4f04ec9e52dd219ee01387c6191f449cd10a6c2488b1d2866424b7a8a"}, + {"id":"8cdc4676aca93bbafcfbe6784f9b2df54e8ca20fbe69ba55fda487736bfdb7f6","pubkey":"6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93","created_at":1680636068,"kind":1,"tags":[["e","44d3ecbb5752e96becc330d9b56352ea595d37b4c55edd8701fd24f18df5eee2"],["e","d4a0b4f08d98d82a04292654ec132723cc2cf3fa24ffb6c0833426cb9372f4d5"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["p","39a8b17475be0db44e313f9fd032ffde183c8abd6498e4932a873330d2cd4868"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"we early ","sig":"b8026e43c61b491014915caf79289968b87e52aa87a487ebecbf6cb2b3c07d460f2ab1a86da99b1c5410a0f5d14e77cf27f78c56bf1ab709f0d616ad2711de78"}, + {"id":"e15b386824fbfdcbf1b50b8860f03062cef534a3ea5339cc837536fb2a58465e","pubkey":"d3d2b986796c9e2067c58fc9017cace5adc1876e9b674719078d5c13d82e54a9","created_at":1690025613,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"]],"content":"test 3","sig":"1a34f9bb9eca624f4e0c3de2ad4ad7d9c915cd16e3f1e41066a69d3799a5bb19689a8e0d894e00649cae7f7d27beadbab2b04d4083f7f2ce68e5ee65af229f55"}, + {"id":"ba9a8a1a8afb0b53fb5d4fa3f5130fe557a8d8d56fac7af9ad3443531d2a2933","pubkey":"95181f816dc80a141e9158a2a398bec37f580f4309633321a1ca53757bf08794","created_at":1690373626,"kind":1,"tags":[["e","e15b386824fbfdcbf1b50b8860f03062cef534a3ea5339cc837536fb2a58465e"],["p","d3d2b986796c9e2067c58fc9017cace5adc1876e9b674719078d5c13d82e54a9"]],"content":"I see your tests. 1-3 🫡","sig":"cc8d3af65578cc2436878fb5dbf3ac27751b50f91b02dd944094e9f9f2965193e32fb20ce68cfe5555ecfb4b13fd06b9cdb673dc71e5db47199b8e6cde2d2e60"}, + {"id":"b0425132a3dd4142a0f78986166aaa28021cc8fb440c95c321a95afce3d5e056","pubkey":"d3d2b986796c9e2067c58fc9017cace5adc1876e9b674719078d5c13d82e54a9","created_at":1690025593,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"]],"content":"test 2","sig":"0226d5836991836ba105cd483def0baa4255bad19a8213ae483c0168efb4de6e493233ed1fdc83e038d5227e0254dc0b461e7a7fa8032a7eada56b9840e8762f"}, + {"id":"e9bb4e2d56bd2be2952570bd52b102c23444a62ada5b78ba086f086d9147651a","pubkey":"d3d2b986796c9e2067c58fc9017cace5adc1876e9b674719078d5c13d82e54a9","created_at":1690025573,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"]],"content":"test","sig":"ba66f1123e93a70645f3f01814378d23609cc2fda38f083410e0e06b037dc9fc45d139b690e2e892278f768c97a03e02e0a9cd0a8b385271db180e1e8838784d"}, + {"id":"4d7b21c462f3fbf27a1882dbaaec4e99e5a5d18a2c18d1f2d1f0736684ad157c","pubkey":"84142dede040f7e0852ba867cfa921986b7b7e92c4b7bc5c72fbd2a4577545e4","created_at":1688308094,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"]],"content":"testing","sig":"9f991643229822577c967d6d71831a6d98993dbbd3613b04abda0907a944b8eb20f6f8477bc8e922308e2e2135243ab78a31a93f285ee6215ac5536141a7d95d"}, + {"id":"9cdbced750e6b1e1274b7df47cb433f565414dd08c897167eba761eadee841cc","pubkey":"726a1e261cc6474674e8285e3951b3bb139be9a773d1acf49dc868db861a1c11","created_at":1687990252,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"]],"content":"Running zapthreads","sig":"1cd2209548f5a791807e4a8aeafbf3a2fb28cee013ad5f444f86dffd448668c05480d7714b892314f5fa50b7c65a23708362c1d5b0cb669c64cfb06ca8486ba9"}, + {"id":"5799aac7a9b06f3cae3d3791b79df29d14173515cfdbf34398aab73ed4a44121","pubkey":"726a1e261cc6474674e8285e3951b3bb139be9a773d1acf49dc868db861a1c11","created_at":1687996513,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"],["e","9cdbced750e6b1e1274b7df47cb433f565414dd08c897167eba761eadee841cc","","reply"]],"content":"Testing nested comments","sig":"335f9969d23e28fef45adfda63da236f1d4d72dfb5873fc78961d47ee948e9333632ce8a45df3c09fc431cf8d29d2fb99bea9c9a4b3502465b05a0328d563231"}, + {"id":"7a18dda355525d468b31bba4fa947cba98cc19048d4a3099d5e9ba045d878c26","pubkey":"45c41f21e1cf715fa6d9ca20b8e002a574db7bb49e96ee89834c66dac5446b7a","created_at":1680618145,"kind":1,"tags":[["e","1a1fe6c838400f3347f97a9adce08c10068f3bc35a279520c911b025c387b061",""],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93",""],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599",""],["title","Purple Text, Orange Highlights"],["summary","Using nostr as a base layer to create, consume, and monetize long-form content."],["image","https://dergigi.com/assets/images/reader.jpg"],["published_at","1680613802"]],"content":"good read. the highlighted part to be a shareable event 1 idea seems interesting, might explore it on flycat","sig":"ee913e997b907a03300616c36cffa12d2362932bd5e249cde39a44ec1250c7622703dddac167b093c3e3a28d41ebfeb9aed9d663d82bea9f8deaed4e342248dc"}, + {"id":"a3b3825af621727f9af3bd77392fe38c04d71658024916af7fe4c5867ef73eaa","pubkey":"619af6a60b3fe4c733aaca061c522cc9c7cf1d87ef4c908facc5ed936d3bdf23","created_at":1681941926,"kind":1,"tags":[["p","330fb1431ff9d8c250706bbcdc016d5495a3f744e047a408173e92ae7ee42dac"],["e","d7ef8220e3521779e2e0c3ff0afb9738f241e44ace8ed1d5237cab36330a69d0"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Good or bad time?","sig":"5629e21769b018c7f050ad35e20c3926e5f9c415ebcd54656e874cff7948a9117de6fb32d18f993b7c96f480f3e4baffb079a3db7c126c74b0188006bba41768"}, + {"id":"c5ad64b1b72776a068c39f4549d089032432814a146849eba0650d1b329fb285","pubkey":"126df36019a793922eae86bfcfedc5240b68d67953892237e3eb500ab92140bf","created_at":1681911407,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","f2610be11393f884c020119316d3304bc06c48ab01f9cbcf5a5a8290031bf20e"],["p","6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"Cool","sig":"62240add277f55e896ae24276fdae60f1580be9de4889e546fd2141b73e07b3e48f225a57914a5e0e5a2fd87570a1dfe1af4f869b355a7c455aa77f395c10bdb"}, + {"id":"6a58f8315af5badb1bdaeb5489417b94621a4d8e192ae2fedcca0c5dcf0c9cd4","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681821926,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","81a6379301d7b517f96cc7d070b5b30fb43db97c5c814be3bc9f58d8fcbaf190"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"test 5","sig":"eeba84f251d8d79e0f16213b766aee8079a3a5018407c3f7d1e8161c762e6a735bb695ac54898e04d7abe245ec12f24d680927351d37a6f31557344adeebd3c2"}, + {"id":"6e9bb03c7c40d67fec0d0bb872548ec207ba0ac4533efa137d7bcaca9fb4b191","pubkey":"fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52","created_at":1681755803,"kind":1,"tags":[["p","fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],["e","9defafc0783f16b2ef9ac02d2e808a103d5d38f12905b7840420634af67d0821"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"test1","sig":"17c2489ee28dc32df68ebf87ced6f5f9af0e3f091b31298fece408acba43236bc6c9f50d756f61bcf46a204e043141535e0cd281d541146cbfac259814cd2cbe"}, + {"id":"e2ae784b239cac4bad38136e4bd758b87dd261b659ef460450064bf9073edcb3","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681648013,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","81a6379301d7b517f96cc7d070b5b30fb43db97c5c814be3bc9f58d8fcbaf190"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"powerful quote 👀","sig":"eda9e5565000892dacab78469936d96aad7fb0dc0828630563b8ccb731f08e704eacfefff246b6bb668332e046f5650f2a9e4186c108f07cba07eefc775c6c58"}, + {"id":"45d4fc726f2cc5b524be862c14fdadc1a24b25b8c6c011eedf2d2909589263e7","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681821952,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","e2ae784b239cac4bad38136e4bd758b87dd261b659ef460450064bf9073edcb3"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"test 7","sig":"e2c35766479d549700f4dbaeae385cfdacee1275ddf24777643ca7d7335c6d1baf7f89ac25d1dc90688bc49f8d2f5e4857d2234035291628a0c0ac760485bab0"}, + {"id":"7a4a2419824669f07081abe2132f8cc0027efbce066ccdf187c897bb7ffa5dc3","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681821936,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","e2ae784b239cac4bad38136e4bd758b87dd261b659ef460450064bf9073edcb3"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"test 5","sig":"875339b3e666fb1013d6563552997dcdd02e87b1f290ad25b0d7dd085d2f87dd10a4e6c20dfe3fc109d1809733b93675505341fe149e4399c42371c743fafc73"}, + {"id":"674c62f84afdc045bc3623ea132d90afdfe4b64249807f65302231115af5406d","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681648340,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","e2ae784b239cac4bad38136e4bd758b87dd261b659ef460450064bf9073edcb3"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"nested reply","sig":"f0f4fdd2d34e59255137c457b9d42fa9b5357e824f3154340de964616f6daf21e3b03491363b0060f97c5061445d7b2854eed328c5cced751b2b480e5ce8ce9a"}, + {"id":"d54761f672669ea4f4b7592f3b0a30ee28de340b0a7e46b91af94e66905171c9","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681648345,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","674c62f84afdc045bc3623ea132d90afdfe4b64249807f65302231115af5406d"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"another one","sig":"dd732eb380542dd8068449d5617bb8b6c1dfe1495c9facbd46aad3ca9b084122479df30861b8e85e13e7b0c9bf9bce589b7fc062daa086c1ff8a0b1d1ffc7aa7"}, + {"id":"00813a18ac9084cd0948c27027a980e34039a3011f30279a8b52ad87da5a3031","pubkey":"73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc","created_at":1681648351,"kind":1,"tags":[["p","73c7f6d5bb599bb7d7cee84c72e89dbd549df53da522ed6c7611055cc0db64bc"],["e","d54761f672669ea4f4b7592f3b0a30ee28de340b0a7e46b91af94e66905171c9"],["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599"]],"content":"yet another one","sig":"6332c8a441439487898fd5b423e42dde7d1d7aadfcf9b36defd78d76d1685ba099ac86ae00a1dac6ed5e8a166422d59bbb93bfccb2596dc1c5461efcfcf345b4"}, + {"id":"87a5bd25aa084cefb3357fc9c2a5b327254fab35fdd7b2d4bd0acddc63d0abe8","pubkey":"726a1e261cc6474674e8285e3951b3bb139be9a773d1acf49dc868db861a1c11","created_at":1687990701,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"],["e","00813a18ac9084cd0948c27027a980e34039a3011f30279a8b52ad87da5a3031","","reply"]],"content":"and another one more","sig":"6a385fb259ff40d9b6bd8bb1d5a2e20057ec1c5b5ed2c307fbc40e4a96d4c191b80b6ea3f3f5748c907d4b0e6e64a92210a0be2889af856ad084ec6806f3cbd8"}, + {"id":"512962dbada5fd5015fc727a107d5c3f569662de67eab8e5da5a8065012cf11e","pubkey":"7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194","created_at":1688194800,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"],["e","87a5bd25aa084cefb3357fc9c2a5b327254fab35fdd7b2d4bd0acddc63d0abe8","","reply"]],"content":"another one","sig":"b4bc4d8206a08de0a918043129b27c8863d17f60e4f58b4d2b535326625870d32640b04f247eb9eb5df1d62fe98c8e1b0341bdd119655553488300ec9d5b4036"}, + {"id":"ce6e32e3e17b6901d2cc70b60f3743e24f885bb6e9da6d88cff516079eac1883","pubkey":"726a1e261cc6474674e8285e3951b3bb139be9a773d1acf49dc868db861a1c11","created_at":1688234921,"kind":1,"tags":[["a","30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599","","root"],["e","512962dbada5fd5015fc727a107d5c3f569662de67eab8e5da5a8065012cf11e","","reply"]],"content":"yet another one, testing 0.0.3","sig":"13bd41c4029c6a7ee41cb03d12e831e9e9b6e14d43a61c78a72657070b45385ba2ce98e8121049fbcbdb7b2dd777c36c7867ba70b5e6a4798a9b866910ae5b62"} + ] + """.trimIndent() + + val header = """ + { + "content": "Not too long ago, I tried to paint a picture of what\na [vision for a value-enabled web][vew]\ncould look like. Now, only a couple of months later,\nall this stuff is being built. On nostr, and on lightning. Orange and\npurple, a match made in heaven.\n\nIt goes without saying that I'm beyond delighted. What a time to be alive!\n\n## nostr\n\nHere's the thing that nostr got right, and it's the same thing that\nBitcoin got right: information is easy to spread and hard to stifle.[^fn-stifle]\nInformation can be copied quickly and perfectly, which is, I believe,\nthe underlying reason for its desire to be free.\n\n[^fn-stifle]: That's a [Satoshi quote][stifle], of course: \"Bitcoin's solution is to use a peer-to-peer network to check for double-spending. In a nutshell, the network works like a distributed timestamp server, stamping the first transaction to spend a coin. It takes advantage of the nature of information being easy to spread but hard to stifle.\"\n\n[stifle]: https://satoshi.nakamotoinstitute.org/posts/p2pfoundation/1/\n\nEasy to spread, hard to stifle. That's the base reality of the nature\nof information. As always, the smart thing is to work with nature, not\nagainst it.[^1] That's what's beautiful about the orange coin and\nthe purple ostrich: both manage to work with the peculiarities of\ninformation, not against them. Both realize that information can and should be\ncopied, as it can be perfectly read and easily spread, always. Both understand\nthat resistance to censorship comes from writing to many places, making the cost\nof deletion prohibitive.\n\n> Information does not just want to be free,\n> it longs to be free. Information expands to fill the available\n> storage space. Information is Rumor's younger, stronger cousin;\n> Information is fleeter of foot, has more eyes, knows more, and\n> understands less than Rumor.\n>\n> Eric Hughes, [A Cypherpunk's Manifesto][manifesto]\n\n[manifesto]: https://nakamotoinstitute.org/static/docs/cypherpunk-manifesto.txt\n\nNostr is quickly establishing itself as a base layer for information exchange,\none that is identity-native and value-enabled. It is distinctly different from\nsystems that came before it, just like Bitcoin is distinctly different from\nmonies that came before it.\n\nAs of today, the focus of nostr is mostly on short text notes, the so-called\n\"type 1\" events more commonly known as *tweets*.[^fn-kinds] However, as you should be aware\nby now, nostr is way more than just an alternative to twitter. It is a new\nparadigm. Change the note kind from `1` to `30023` and you don't have an\nalternative to Twitter, but a replacement for Medium, Substack, and all the\nother long-form platforms. I believe that special-purpose clients that focus on\ncertain content types will emerge over time, just like we have seen the\nemergence of special-purpose platforms in the Web 2.0 era. This time, however,\nthe network effects are cumulative, not separate. A new paradigm.\n\nLet me now turn to one such special-purpose client, a nostr-based reading app.\n\n[^fn-kinds]: Refer to the various NIPs to discover the multitude of [event kinds][kinds] defined by the protocol.\n\n[kinds]: https://github.com/nostr-protocol/nips#event-kinds\n[nip23]: https://github.com/nostr-protocol/nips/blob/master/23.md\n\n## Reading\n\nI'm constantly surprised that, even though most people do read a lot\nonline, very few people seem to have a reading workflow or reading\ntools.\n\nWhy that is is anyone's guess, but maybe the added value of such tools\nis not readily apparent. You can just read the stuff right there, on the\nad-ridden, dead-ugly site, right? Why should you sign up for another\nsite, use another app, or bind yourself to another closed platform?\n\nThat's a fair point, but the success of Medium and Substack shows that\nthere is an appetite for clean reading and writing, as well as providing\navenues for authors to get paid for their writing (and a willingness of\nreaders to support said authors, just because).\n\nThe problem is, of course, that all of these platforms are *platforms*,\nwhich is to say, walled gardens that imprison readers and writers alike.\nWorse than that: they are fiat platforms, which means that\npermissionless value-flows are not only absent from their DNA, they are\noutright impossible.[^2]\n\nNostr fixes this.\n\n![Nostriches like to read, or so I've heard](https://dergigi.com/assets/images/bitcoin/2023-04-04-purple-text-orange-highlights/nostrich-reading-a-newspaper.jpg)\n\nThe beauty of nostr is that it is not a platform. It's a protocol,\nwhich means that you don't have to sign up for it---you can create an\nidentity yourself. You don't have to ask for permission; you just *do*,\nwithout having to rely on the benevolence of whatever dictator is in\ncharge of the platform right now.\n\nNostr is *not* a platform, and yet, powerful tools and services can be\nbuilt and monetized on top of it. This is good for users, good for\nservice providers, and good for the network(s) at large. Win-win-win.\n\nSo what am I talking about, exactly? How can nostr improve everyone's\nreading (and writing) experience?\n\nAllow me to paint a (rough) picture of what I have in mind. Nostr\nalready supports private and public bookmarks, so let's start from\nthere.\n\nImagine a special-purpose client that scans all your bookmarks for long-form\ncontent.[^fn-urls] Everything that you marked to be read later is shown in an orderly\nfashion, which is to say searchable, sortable, filterable, and displayed without\ndistractions. Voilà, you have yourself a reading app. That's, in essence, how\nPocket, Readwise, and other reading apps work. But all these apps are walled\ngardens without much interoperability and without direct monetization.\n\n[^fn-urls]: In the nostr world long-form content is simply markdown as defined in [NIP-23][nip23], but it could also be a link to an article or PDF, which in turn could get [converted into markdown][readability] and posted as an event to a special relay.\n\n[readability]: https://github.com/mozilla/readability\n\nBitcoin fixes the direct monetization part.[^fn-v4v] Nostr fixes the interoperability part.\n\n[^fn-v4v]: ...because Bitcoin makes [V4V][busking] practical. (Paywalls are not the way.)\n\nAlright, we got ourselves a boring reading app. Great. Now, imagine that\nusers are able to highlight passages. These highlights, just like\nbookmarks now, could be private or public. When shared publicly,\nsomething interesting emerges: an overlay on existing content, a lens on\nthe written Web. In other words: *swarm highlights*.\n\nImagine a visual overlay of all public highlights, automatically shining\na light on what the swarm of readers found most useful, insightful,\nfunny, etc.\n\n![Swarm Highlights](https://dergigi.com/assets/images/bitcoin/2023-04-04-purple-text-orange-highlights/highlights.png)\n\nFurther, imagine the possibility of sharing these highlights as a \"type 1\" event\nwith one click, automatically tagging the highlighter(s)---as well as the\nauthor, of course---so that eventual sat-flows can be split and forwarded\nautomatically.\n\n![Automated value splits](https://dergigi.com/assets/images/bitcoin/2023-04-04-purple-text-orange-highlights/sat-flows.png)\n\nVoilà, you have a system that allows for value to flow back to those who\nprovide it, be it authors, editors, curators, or readers that willingly\nslog through the information jungle to share and highlight the best\nstuff (which is a form of curation, of course).\n\nZaps make nostr a defacto address book[^fn-pp] of payment information, which is\nto say lightning addresses, as of now. Thanks to [nostr wallet connect][nwc] (among\nother developments), sending sats ~~will soon be~~ is already as\nfrictionless as leaving a like.\n\n[^fn-pp]: The Yellow Pages are dead, long live [The Purple Pages](http://purplepag.es/)!\n\nValue-for-value and participatory payment flows are something that\ntraditional reading apps desperately lack, be it Pocket, Instapaper,\nReadwise, or the simple reading mode that is part of every browser.\n\nA neat side-effect of a more structured way to share passages of text is\nthat it enables semi-structured discussions around said\npassages---which could be another useful overlay inside\nspecial-purpose clients, providing context and further insights.[^5]\n\nFurther, imagine the option of seamlessly switching from text-on-screen\nto text-to-speech, allowing the user to stream sats if desired, as\nPodcasting 2.0 clients already do.[^3]\n\nImagine user-built curations of the best articles of the week, bundled\nneatly for your reading pleasure, incentivized by a small value split\nthat allows the curator to participate in the flow of sats.\n\nYou get the idea.\n\nI'm sure that the various implementation details will be hashed out,\nbut as I see it, 90% of the stuff is already there. Maybe we'll need\nanother NIP or two, but I don't see a reason why this can't be\nbuilt---and, more importantly: I don't see a reason why it wouldn't\nbe sustainable for everyone involved.\n\nMost puzzle pieces are already there, and the rest of them can probably\nbe implemented by custom event types. From the point of view of nostr,\nmost everything is an event: bookmarks are events, highlights are\nevents, marking something as read is an event, and sharing an excerpt or\na highlight is an event. Public actions are out in the open, private\nactions are encrypted, the data is not in a silo, and everyone wins.\nEspecially the users, those who are at the edge of the network and\nusually lose out on the value generated.\n\nIn this case, the reading case, the users are mostly \"consumers\" of\ncontent. What changes from the producing perspective, the perspective of\nthe writer?\n\n## Writing\n\nBack to the one thing that nostr got right: information is easy to\nspread but hard to stifle. In addition to that, digital information can\nbe copied perfectly, which is why it shouldn't matter where stuff is\npublished in the first place.\n\nAllow me to repeat this point in all caps, for emphasis: **IT SHOULD NOT\nMATTER WHERE INFORMATION IS PUBLISHED**, and, maybe even more\nimportantly, it shouldn't matter if it is published in a hundred\ndifferent places at once.[^fn-torrents]\n\nWhat matters is trust and accuracy, which is to say, digital signatures\nand reputation. To translate this to nostr speak: because every event is\nsigned by default, as long as you trust the person behind the signature,\nit doesn't matter from which relay the information is fetched.\n\nThis is already true (or mostly true) on the regular web. Whether you\nread the internet archive version of an article or the version that is\npublished by an online magazine, the version on the author's website,\nor the version read by some guy that has read more about Bitcoin than\nanyone else you know[^fn-guy]---it's all the same, essentially. What matters\nis the information itself.\n\n[^fn-guy]: There is only one such guy, as we all know, and it's this Guy: nostr:npub1h8nk2346qezka5cpm8jjh3yl5j88pf4ly2ptu7s6uu55wcfqy0wq36rpev\n\nPractically speaking, the source of truth in a hypernostrized world is---you\nguessed it---an event. An event signed by the author, which allows for\nthe information to be wrapped in a tamper-proof manner, which in turn\nallows the information to spread far and wide---without it being\nhosted in one place.\n\nThe first clients that focus on long-form content already exist, and I expect\nmore clients to pop up over time.[^4] As mentioned before, one could easily\nimagine [prism-like value splits][prism] seamlessly integrated into these\nclients, splitting zaps automatically to compensate writers, editors,\nproofreaders, and illustrators in a V4V fashion. Further, one could imagine\nvarious compute-intensive services built into these special-purpose clients,\nsuch as GPT Ghostwriters, or writing aids such as Grammarly and the like. All\nthese services could be seamlessly paid for in sats, without the requirement of\nany sign-ups or the gathering of any user data. That's the beauty of [money\nproper][rediscovery].\n\n![A clean and simple reading and writing interface](https://dergigi.com/assets/images/bitcoin/2023-04-04-purple-text-orange-highlights/nostr-reader-and-writer.png)\n\nPlagiarism is one issue that needs to be dealt with, of course. Humans\nare greedy, and some humans are assholes. Neither bitcoin nor nostr\nfixes this. However, while plagiarism detection is not necessarily\ntrivial, it is also not impossible, especially if most texts are\npublished on nostr first. Nostr-based publishing tools allow for\nOpenTimestamp attestations thanks\nto [NIP-03](https://github.com/nostr-protocol/nips/blob/master/03.md),\nwhich in turn allows for plagiarism detection based on \"first seen\"\nlookups.\n\nThat's just one way to deal with the problem, of course. In any case,\nI'm confident that we'll figure it out.\n\n## Value\n\nI believe that in the open ~~attention~~ information economy we find\nourselves in, value will mostly derive from effective curation,\ndissemination, and transmission of information, *not* the exclusive\nownership of it.\n\nAlthough it is still early days,\nthe [statistics](https://stats.podcastindex.org/v4v) around Podcasting\n2.0 and [nostr zaps](https://zaplife.lol/) clearly show that (a) people\nare willing to monetarily reward content they care about, and (b) the\nwillingness to send sats *increases* as friction *decreases*.\n\nThe ingenious thing about boostagrams and zaps is that they are direct\nand visible, which is to say, public and interactive. They are neither\nregular transactions nor simple donations---they are something else\nentirely. An unforgable value signal, a special form of gratitude and\nappreciation.\n\nContrast that with a link to Paypal or Patreon: impersonal, slow,\nindirect, and friction-laden. It's the opposite of a super-charged\ninteraction.\n\nWhile today's information jungle increasingly presents itself in the\nform of (short) videos and (long-form) audio, I believe that we will see\na renaissance of the written word, especially if we manage to move away\nfrom an economy built around attention, towards an economy built upon\nvalue and insight.\n\nThe orange future now has a purple hue, and I believe that it will be as\nbright as ever. We just have a lot of building to do.\n\n---\n\n## Further Reading\n\n- [A Vision for a Value-Enabled Web][vew]\n- [The Freedom of Value][busking]\n- [The Rediscovery of Money][prism]\n- [Lightning Prisms][rediscovery]\n\n[vew]: https://dergigi.com/vew\n[prism]: https://dergigi.com/prism\n[rediscovery]: https://dergigi.com/rediscovery\n[busking]: https://dergigi.com/busking\n\n## NIPs and Resources\n\n- [Nostr Resources][nr]\n- [value4value.info](https://value4value.info/)\n- [nips.be](https://nips.be/)\n- [NIP-23: Long-form content](https://github.com/nostr-protocol/nips/blob/master/23.md)\n- [NIP-57: Event-specific zap markers](https://github.com/nostr-protocol/nips/blob/master/57.md)\n- [NIP-47: Nostr Wallet Connect](https://github.com/getAlby/nips/blob/master/47.md)\n- [NIP-03: OpenTimestamps attestations for events](https://github.com/nostr-protocol/nips/blob/master/03.md)\n\nOriginally published on [dergigi.com](https://dergigi.com/reader)\n\n---\n\n[^1]: Paywalls work against this nature, which is why I consider them misguided at best and incredibly retarded at worst.\n\n[^2]: Fiat doesn't work for the [value-enabled web][vew], as fiat rails can never be open and permissionless. Digital fiat is never money. It is---and always will be---[credit][rediscovery].\n\n[^3]: Whether the recipient is a text-to-speech service provider or a human narrator doesn't even matter too much, sats will flow just the same.\n\n[^4]: [BlogStack](https://blogstack.io/) and [Habla](https://habla.news/) being two of them.\n\n[^5]: Use a URI as the discussion base (instead of a highlight), and you got yourself a [Disqus](https://disqus.com/) in purple feathers!\n\n[^fn-torrents]: That's what torrents got right, and [ipfs] for that matter.\n\n[nr]: https://nostr-resources.com\n[nwc]: https://nwc.getalby.com/\n[ipfs]: https://fiatjaf.com/d5031e5b.html\n", + "created_at": 1680614039, + "id": "9517aa60334990596fdea4493c1bde429c55e9cefb84d8d88a6758c4e3ebcabc", + "kind": 30023, + "pubkey": "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93", + "sig": "c8c8c7ac8c288f6a6e1090e0e5f7eed85daaaba03eeab0a4936535f95ce066c08723bedcfb80a6af4941a9fafb9fe351950b9376d13ff0e81030cd4391840f04", + "tags": [ + ["d","1680612926599"], + ["title","Purple Text, Orange Highlights"], + ["summary","Using nostr as a base layer to create, consume, and monetize long-form content."], + ["published_at","1680613802"], + ["t","nostr"], + ["t","reading"], + ["t","writing"], + ["t","readability"], + ["t","highlights"], + ["t","pocket"], + ["t","instapaper"], + ["t","readwise"], + ["t","disqus"], + ["t","v4v"], + ["t","value4value"], + ["image","https://dergigi.com/assets/images/reader.jpg"], + ["p","b9e76546ba06456ed301d9e52bc49fa48e70a6bf2282be7a1ae72947612023dc"] + ] + } + """.trimIndent() + + @Test + fun threadOrderTest() { + val eventArray = Event.mapper.readValue>(db) as List + Event.fromJson(header) + + var counter = 0 + eventArray.forEach { + TestCase.assertTrue("${it.id} failed signature check", it.hasValidSignature()) + LocalCache.verifyAndConsume(it, null) + counter++ + } + + val naddr = ATag(30023, "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93", "1680612926599", null) + + val filter = ThreadFeedFilter(naddr.toTag()) + val calculatedFeed = filter.feed() + + val expecteedOrder = listOf( + "30023:6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93:1680612926599", + "e15b386824fbfdcbf1b50b8860f03062cef534a3ea5339cc837536fb2a58465e", + "ba9a8a1a8afb0b53fb5d4fa3f5130fe557a8d8d56fac7af9ad3443531d2a2933", + "b0425132a3dd4142a0f78986166aaa28021cc8fb440c95c321a95afce3d5e056", + "e9bb4e2d56bd2be2952570bd52b102c23444a62ada5b78ba086f086d9147651a", + "4d7b21c462f3fbf27a1882dbaaec4e99e5a5d18a2c18d1f2d1f0736684ad157c", + "9cdbced750e6b1e1274b7df47cb433f565414dd08c897167eba761eadee841cc", + "5799aac7a9b06f3cae3d3791b79df29d14173515cfdbf34398aab73ed4a44121", + "741f5367a9415f4d6f19c0f57a1e4647c8ed8309b53b0da2d82fc4ebfba03b2c", + "22323fc72b4c37f93ea21f6069684339ce5f63111161c81f2aa3de4a21bfe83b", + "14525fcaae530a029f782fd361dd0cd66634c3e23020bd19e66fe11c1e254e32", + "98ae0d6d10e494ed0bf70feb577e8225c6a6732c7af3d29f88bfe1b87d4439e6", + "36e262e71b7e8bcae946f69885b8c3614e318e82864437342cf50e8b9ab7229d", + "37725c2924ca267d66c2c27c2dae65550c07e7b883034cf1ea69671883430642", + "8ba54cfb6375270e8ae97a7e0992c1a0dbaa4cd46af8309d67a839e86789fde6", + "53410bc6d47e87f3f18ecbc93c716b5a6ef8ee3805516b2ff4d155154a685b7c", + "a3b3825af621727f9af3bd77392fe38c04d71658024916af7fe4c5867ef73eaa", + "e383476cb1ce5accde11d4b1338424fa32c3724cf96e6214af8e5e852981728a", + "e2d8aaed336d3c0f73a9ca46a89fdb2da62a6d172936a91b0067a68797b3bcb8", + "b92e4d6a5d0e8d1d2d2421044b84a4d11f2188261c55145d782b1b6bf0995009", + "da13e14cc8bcc243e0373dde14533d3829b8b621e214ca3c99c90f3dd9e11b8a", + "b5234d90a1543ba60765c57ac3fc7140129a4ac28bbd013531ec9b85e256ea55", + "c5ad64b1b72776a068c39f4549d089032432814a146849eba0650d1b329fb285", + "fc4e4a1230b002e4ae08251a0b26107de7f518800188b7a504f5de62d8b07996", + "6a58f8315af5badb1bdaeb5489417b94621a4d8e192ae2fedcca0c5dcf0c9cd4", + "6e9bb03c7c40d67fec0d0bb872548ec207ba0ac4533efa137d7bcaca9fb4b191", + "e2ae784b239cac4bad38136e4bd758b87dd261b659ef460450064bf9073edcb3", + "45d4fc726f2cc5b524be862c14fdadc1a24b25b8c6c011eedf2d2909589263e7", + "7a4a2419824669f07081abe2132f8cc0027efbce066ccdf187c897bb7ffa5dc3", + "674c62f84afdc045bc3623ea132d90afdfe4b64249807f65302231115af5406d", + "d54761f672669ea4f4b7592f3b0a30ee28de340b0a7e46b91af94e66905171c9", + "00813a18ac9084cd0948c27027a980e34039a3011f30279a8b52ad87da5a3031", + "87a5bd25aa084cefb3357fc9c2a5b327254fab35fdd7b2d4bd0acddc63d0abe8", + "512962dbada5fd5015fc727a107d5c3f569662de67eab8e5da5a8065012cf11e", + "ce6e32e3e17b6901d2cc70b60f3743e24f885bb6e9da6d88cff516079eac1883", + "d4a0b4f08d98d82a04292654ec132723cc2cf3fa24ffb6c0833426cb9372f4d5", + "8cdc4676aca93bbafcfbe6784f9b2df54e8ca20fbe69ba55fda487736bfdb7f6", + "7a18dda355525d468b31bba4fa947cba98cc19048d4a3099d5e9ba045d878c26" + ) + + for (i in expecteedOrder.indices) { + assertEquals(expecteedOrder[i], calculatedFeed[i].idHex) + } + } +} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt index 5a27927f9..5045abc16 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt @@ -120,17 +120,24 @@ open class Note(val idHex: String) { /** * This method caches signatures during each execution to avoid recalculation in longer threads */ - fun replyLevelSignature(cachedSignatures: MutableMap = mutableMapOf()): String { + fun replyLevelSignature( + eventsToConsider: Set, + cachedSignatures: MutableMap + ): String { val replyTo = replyTo if (event is RepostEvent || event is GenericRepostEvent || replyTo == null || replyTo.isEmpty()) { return "/" + formattedDateTime(createdAt() ?: 0) + ";" } - return replyTo + val mySignature = replyTo + .filter { it in eventsToConsider } // This forces the signature to be based on a branch, avoiding two roots .map { - cachedSignatures[it] ?: it.replyLevelSignature(cachedSignatures).apply { cachedSignatures.put(it, this) } + cachedSignatures[it] ?: it.replyLevelSignature(eventsToConsider, cachedSignatures).apply { cachedSignatures.put(it, this) } } .maxBy { it.length }.removeSuffix(";") + "/" + formattedDateTime(createdAt() ?: 0) + ";" + + cachedSignatures[this] = mySignature + return mySignature } fun replyLevel(cachedLevels: MutableMap = mutableMapOf()): Int { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt index 1612d85cb..411d37104 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt @@ -14,8 +14,9 @@ class ThreadFeedFilter(val noteId: String) : FeedFilter() { override fun feed(): List { val cachedSignatures: MutableMap = mutableMapOf() val eventsToWatch = ThreadAssembler().findThreadFor(noteId) ?: emptySet() + // Currently orders by date of each event, descending, at each level of the reply stack - val order = compareByDescending { it.replyLevelSignature(cachedSignatures) } + val order = compareByDescending { it.replyLevelSignature(eventsToWatch, cachedSignatures) } return eventsToWatch.sortedWith(order) }